-1

I'm pretty new with React so I need your help.

I have a component with multiple inputs, so i have to validate them.

Submit button is disabled by default, and only if the inputs are not blank, I make it able to Submit.

If I delete the value inside the input, button should go back to disabled.

My problem is, this function(validate function) works only in debugger when I go step by step.

Can someone help me? Here are segments of my code that I find useful to understand my problem.

this.state = {
            profile: newProfile,
            disable: true,

        };



let newProfile= {
            firstName: "",
            lastName: "",
            nickname: "",
            email: ""
        };

 validate = () => {
        console.log(this.state)
        debugger;
        if (!this.state.profile.name || !this.state.profile.email) {
            return false;
        } else {
            console.log("Profile name and email NOT BLANK")
            console.log(this.state)
            return true;
        }
    };


profileChange= ((target, value) => {
            this.setState(prevState => {
                let profile= this.state.profile;
                profile[target] = value;
                    return {
                        profile: profile,

                    }

            })

 const isValid = this.validate();
        if (isValid) {
            console.log("valid inputs");
            this.setState({disable: false});
        }
        else{
            console.log("invalid inputs");
            this.setState({disable: true});
        }

    });
lagertha6
  • 39
  • 1
  • 5

3 Answers3

0

The setState function is asynchronous, which means that wile the state is being updated, other functions could be fired.

What I think is happening in your case, is that the state is being updated, but before that happened, this.validate() is already called.

To fix this, you have to add the code you would like to fire after you updated that state, as callback:

this.setState(prevState => {
    let profile= this.state.profile;
    profile[target] = value;

    return {
        profile: profile,
    }
}, () => {
    const isValid = this.validate();

    if (isValid) {
        console.log("valid inputs");
        this.setState({disable: false});
    } else {
        console.log("invalid inputs");
        this.setState({disable: true});
    }
});
Eran Machiels
  • 729
  • 2
  • 8
  • 17
0

setState is an asynchronous function (Why?) and at the point where you are calling this.validate, this.state.profile hasn't been set yet.

But when you are walk through the execution step by step, the state is being updated to the value you want and hence it is working for you.

The solution here is to use the callback function that setState provides to execute validate only after the state is set.

profileChange = (target, value) => {
  this.setState(prevState => {
    return {
      profile: {
        ...prevState.profile,
        [target]: value,
      }
    };
  }, () => {
    const isValid = this.validate();
    if (isValid) {
      console.log("valid inputs");
      this.setState({ disable: false });
    } else {
      console.log("invalid inputs");
      this.setState({ disable: true });
    }
  });
};

Also note that I have used prevState inside the setState instead of this.state, so that the profile state is not actually mutated.

Agney
  • 18,522
  • 7
  • 57
  • 75
-1

you can use "disabled" params on input here's an example

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" disabled={!this.state.value}/>
      </form>
    );
  }
} 

and here's a codepen i made for you to test faster ragnar

Farouk YD
  • 102
  • 2
  • 7