I currently have a form and I'm struggling to detect if the user has inputted.
The scenario is that after inputting the form, the user cancels and a modal will appear that asks if they want to proceed without changing.
const [name, setName] = useState('')
My code for triggering the modal
if (!name){
showModal()
}
Right now I'm having trouble detecting if form has been filled.
you can use "onChange" event to detect input element changes in the form.
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Example From: https://reactjs.org/docs/forms.html
Related
I am following this React tutorial, and I am trying to understand everything going on in the following code segment. Could someone explain what the handleChange() is doing and why it is important?
Is it for storing the inputted information so the back-end can process/store it?
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
handleChange is Calling whenever you are entering any text to input Name
And
`
handleChange(event) {
this.setState({value: event.target.value});
}
`
This is updating your state's this.state value and the same state's value used by input to show the current input value={this.state.value} by you.
Take An example Suppose that you enter "Farro" as input, every time you enter handleChange will be called and update state value As "Farro" and in input field will show "Farro".
The this.handleChange is triggered by the input element and triggers the changing of the this.state.value property which in turn changes the value of the input field. This is important because react uses states to display information in the DOM.
You could name the handleChange whatever you want just as long as it is triggered from the input field & the value updates the state.
here is some additional reading: https://reactjs.org/docs/forms.html
I have two text fields id and name of the user . Below that a submit button .
How can I pass the user name and Id to handleSubmit() on click of the submit buton ?
<input type="text" name="name" id="name" />
<br/>
<label>id : </label>
<input type="text" name="userId" id="userId" />
<br />
<input type="submit" oncClick={()=>this.handleSubmit()}value="Add
user"/>
The value should be saved in the state of the component and updated onChange. Once handleSubmit is called you read the value from the state. const { name } = this.state
class form extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit() {
console.log(this.state.value)
}
render() {
.....
}
}
Given a react controlled component like the following from the react docs:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
What is the right way to change NameForm's state.value from NameForm's parent component? In my specific use case, the user can type in the text input or the user can click some buttons in the parent that are meant to change the value of the input in the child component.
Edit: I should add that I m new to react so I may be overlooking the obvious.
I am fairly new to React coming from a JS & Java background. I am still understanding react state properties and have two code samples, one which compiles and one which does not. In the first, I establish the class' state as having one variable str and I work with this variable. This code does not work. In the second, the variable is named value, and it works. Is it not possible to have a variable under a different name or more than one variable in react? Thank you!!
Side Note: The term "works" in this context is the difference between being able to type into the text field or not.
Form Code (Works):
class SomeOtherForm extends React.Component {
constructor(props) {
super(props);
this.state = {
str: '',
};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleValueChanged(event) {
this.setState({str: event.target.value});
}
handleSubmit(event) {
alert('Y.. ' + this.state.str);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type='text' value={this.state.str} onChange={this.handleChange}/>
</label>
<input type='submit' value='Submit'/>
</form>
);
}
}
Form Code (Doesn't Work):
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
In SomeOtherForm there are a few mishaps:
You're calling this.handleChange for the onChange event, but this method doesn't exist (it needs to be changed from handleValueChanged to handleChange)
You haven't bound both handlers to the constructor (you need to add this.handleChange = this.handleChange.bind(this);)
Fixed:
class SomeOtherForm extends React.Component {
constructor(props) {
super(props)
this.state = { str: '' }
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(event) {
this.setState({
str: event.target.value
})
}
handleSubmit(event) {
event.preventDefault()
alert(`Yo shit isssss.. ${this.state.str}`)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
type='text'
value={this.state.str}
onChange={this.handleChange} />
</label>
<input
type='submit'
value='Submit'/>
</form>
)
}
}
In the first example you named the function handleValueChanged NOT handleChange...
This will fix your problem:
<input type='text' value={this.state.str} onChange={this.handleValueChanged}/>
As a side note state in react is an objectand thats it. So referring to state like this
I establish the class' state as having one variable str and I work
with this variable
Isnt actually technically accurate and makes things sound more confusing than they are.
It's totally possible manage different variables in state.
constructor (props) {
super(props)
this.state = {
name: '',
lastname: ''
}
this.handleSubmit = this.handleSubmit.bind(this)
this.handleChange = this.handleChange.bind(this)
}
handleSubmit (event) {
event.preventDefault()
console.log(this.state)
}
handleChange (event) {
const { name, value } = event.target
this.setState({
[name]: value
})
}
render () {
<form onSubmit={this.handleSubmit}>
<input
name='name'
value={this.state.name}
onChange={this.handleChange}
/>
<input
name='lastname'
value={this.state.lastname}
onChange={this.handleChange}
/>
</form>
}
Pay attention to the name of the inputs they should be the same as the variables in your state.
(I know that this is a simple question. Before posting I have tried to find the answer in previous questions. There are many questions regarding setState being asynchronous, about that you can use a callback function, etc., but I didn't find a question similar to the following).
When implementing a simple form in React, like the one that is shown here (under the controlled components title, also copied below):
Since setState is asynchronous, the example isn't guaranteed to work, right? (Since handleSubmit prints this.state.value, but there is no guarantee that it has been set already, when handleSubmit is called).
Is there a way to ensure that handleSubmit is called only after the state changes of all controlled components in a form have been done (and without using redux or something similar)?
Here is the code, copied from the reactjs.org (I am copying it to make sure it can be read even if the URL changes):
lass NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
If you want to be sure you have a current value of an input inside handleSubmit use the passed SyntheticEvent to access inputs from a form.
lass NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
event.preventDefault();
const form = event.currentTarget;
const inputValue = form.elements["user_name"].value;
alert('A name was submitted: ' + inputValue);
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" name="user_name" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}