I'd like to dynamically setState to true, if an input field is empty. This is so I can style each input field when it is empty via css class when its' state is true.
In my current code, it will run through the loop and set the last empty item to true, even though all inputs are empty. In my mind, I thought it should set everything that's empty to true, but looks like the loop will only recognize the last iteration.
How do I setState to true for all inputs that are empty?
HTML:
<form noValidate onSubmit={this.handleSubmit}>
<label>Name</label>
<input className="form-input" type="text" name="name">
<label>Email</label>
<input className="form-input" type="text" name="email">
<label>Message</label>
<input className="form-input" type="text" name="message">
</Form>
State:
this.state = {
errors: {
name: false,
email: false,
message: false,
},
};
JS:
handleSubmit = (e) => {
let inputFields = document.getElementsByClassName('form-input');
for (var i = 0; i < inputFields.length; i++) {
if (inputFields[i].value === '') {
let inputName = inputFields[i].name;
this.setState({
errors: {
[inputName]: true,
},
});
}
}
}
The problem is setState
merges only the root keys into the state.
In your case, your state is { errors { ... } }
, by doing setState({ error: { ... } })
, react replaces your whole error object inside the state.
You can craft the errors
object in the loop, and do setState
only once:
handleSubmit = (e) => {
let inputFields = document.getElementsByClassName('form-input');
let errors = {};
for (var i = 0; i < inputFields.length; i++) {
if (inputFields[i].value === '') {
let inputName = inputFields[i].name;
errors[inputName] = true;
}
}
this.setState({errors});
}
That is the better approach. But, it might help to understand how setState
works if you also look at this approach:
You can move the keys from errors
to the root of your state, so react merges them into the state instead of replacing them.
this.state = {
nameError: false,
emailError: false,
messageError: false,
};
and
this.setState({
[`${inputName}Error`]: true,
});