-1

I'm trying to validate a form in React. Every time input is changed in the field, I try to validate it:

// Consutructor
this.state{
  Form_errors:
     Key1: false,
     Key2: false
}
handleChange(e, name){
                
    this.setState({
        [name]: e.target.valueAsNumber
    });
                
    // validate fields
    this.validate_field(e, name);
}

Then on form submit, I check every field is true:

handle_submit(e){
    e.preventDefault(); 
                
    // validate form immediately                
    this.validate_form();
}

validate_form(){        
    // check all fields are true
    for (var field in this.state.form_errors) {
        if(!this.state.form_errors[field]){
            this.setState({
                validated: false
            });                     
            return false;
        }
    }
                
    this.setState({
        validated: true
    });
}

At this stage, validate_form() only sees the recent field that was updated in handleChange, so returns true after 1 iteration. If I console.log the current state, only the current key value exists and not the others.

I also have conditional class in render() that also sees only a single field at a time.

Why are the rest of the fields missing in state?

ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • Welcome to SO! Your question would be clearer if you wouldn't mind editing your post to show your render function and state. What's going on with `this.state.form_errors` -- where is that set? Zooming back and explaining what you're trying to achieve at a high level might be useful as well because there could be a fundamentally more elegant way to go about doing it than your attempt. Thanks. – ggorlen Jul 05 '21 at 16:28
  • this.state.form_errors is set at the constructor. Very simply: this.state{form_errors: {key1: false, key2:false}} The render doesnt make a difference, why is console.log(this.state) missing form_error.key2? – Certain Carl Jul 05 '21 at 17:03
  • Where's `console.log(this.state)` in the code? State updates are asynchronous, so if you're doing `this.setState({foo: "bar"}); console.log(this.state)` you won't see `foo: "bar"`. See [setState doesn't update the state immediately](https://stackoverflow.com/questions/41278385/setstate-doesnt-update-the-state-immediately). Please edit your question rather than adding code in the comments. To get an answer to your question, the behavior has to be reproducible, preferably with a [stack snippet](https://meta.stackoverflow.com/a/338538). See [mcve]. Thanks. – ggorlen Jul 05 '21 at 17:08
  • @ggorlen, console log is just an example, the loop in validate_form runs for a single iteration. I added the state in the code. – Certain Carl Jul 05 '21 at 17:16

1 Answers1

0

The state was being reset when only a single property was updated.

this.setState({
  [property]: newVal
});

It means that this.state.property2 would be 'forgotten'. Doing:

this.setState({
  ...this.state,
  [property]: newVal
});
Nimantha
  • 6,405
  • 6
  • 28
  • 69