Q:

React component props are one step behind my validation function

I have written a validation function that validates user input as the inputs change. I've also created an <Input/> component and integrated the error message <div>. So I want to pass a string to a "message" prop on the <Input/> component whenever there is an error and I expect the <div> inside the component to render the error message.
Now I'm sure my validation function works pretty fine. But it seems the "message" prop (or the whole component) is always one step behind the new validation state.
Here's the code:
import React, { Component } from "react";
import Input from "../common/Input";
import Validator from "../../lib/validator/validator";

class Login extends Component {
  constructor(props) {
    super(props);

      this.state = {
        phoneNo: '',
        password: ''
      };

    this.handleChange = this.handleChange.bind(this);
    this.validator = new Validator(rules);
    this.validation = this.validator.validate(this.state);

  }
}

  render() {
return (
  <div className="container d-flex justify-content-center align-items-center full-height">
    <form className="form-container d-flex flex-column justify-content-center align-items-center">
      <div className="title-container d-flex justify-content-center align-items-center">
        <h3 className="spacing">ورود</h3>
      </div>

      <Input type="text" value={this.state.phoneNo} name="phoneNo"
        onChange={this.handleChange} message={this.validation.phoneNo.message}/>

      <Input type="password" value={this.state.password} name="password" 
        onChange={this.handleChange} message={this.validation.password.message}/>

      <Button styleClass="btn btn-primary" type="button" 
        onClick={this.handleSubmit} disabled={!this.validation.isValid}/>

    </form>
  </div>
)
}
  handleChange(e) {
    const name = e.target.name;
    const value = e.target.value;
    this.setState({
      [name]: value
    }, () => {
      this.validation = this.validator.validate(this.state);
      console.log('this validation', this.validation.isValid);
    });
  }

The this.validation = this.validator.validate(this.state); is a variable that contains the returned object from the validation function (which contains validation results). The properties of this variable is used in the "message" prop.
As you can see the state is updated before being validated.
The problem is whenever the fields are valid the console.log('this validation', this.validation.isValid) logs the correct result. But the view is still showing the error messages (from the <Input/> component). It's always one step behind the right state of the form. Since I'm new to react (I used to work with Angular) there might be a mistake that I've made. Any ideas??
Thanks for reading...

A:

Your component will only render when its state changes; when you do the setState it will render, however at that point you haven't updated your validation yet. When you then run your validator check, it does not re-render again.
Hence you get a render with the correct [name]: value data, but the validator (at the point of re-render) is still as it was.
Add the validation check before the setState and store the results of validation in the state as well. Then when setState is called, the re-render will show the correct information.

