Search code examples
javascriptreactjsasynchronoussetstate

Reactjs setState not being updated immediately


I have a function where I'm trying to get an array of emails and checking if it is a valid email:

handleValidEmail = (isValid, index, emailValue) => {
  // checks if empty state in optional fields.
  const { emailValueList, isValidEmailArray, isValidEmail } = this.state;

  // need to make copy, to treat the array as immutable
  const newEmailValueList = [...emailValueList];
  newEmailValueList[index] = emailValue;

  const newIsValidEmailArray = [...isValidEmailArray];
  newIsValidEmailArray[index] = isValid;

  this.setState({
    emailValueList: newEmailValueList,
    isValidEmailArray: newIsValidEmailArray,
  }, () => {
    console.log(emailValueList, isValidEmailArray);
    console.log('before', isValidEmail);

    if (every(isValidEmailArray, Boolean)) {
      this.setState({ isValidEmail: isValid });
    } else {
      this.setState({ isValidEmail: false });
    }
    console.log('isvalidEmail', isValidEmail);
  });
}

So I did some digging, and I know that if you do a callback to your setState, it should work. However, I'm not getting mine to work.

So when I'm typing in the input field: "[email protected]", the console logs:

console.log(emailValueList, isValidEmailArray); = ["[email protected]"], [false]

console.log('before', isValidEmail); = before false

console.log('isvalidEmail', isValidEmail); = isvalidEmail false

When I type the last letter, "m", to make it [email protected]

console.log(emailValueList, isValidEmailArray); = ["[email protected]"], [true]

console.log('before', isValidEmail); = before false

console.log('isvalidEmail', isValidEmail); = isvalidEmail false

Then when I add another letter at the end:

console.log(emailValueList, isValidEmailArray); = ["[email protected]"], [true]

console.log('before', isValidEmail); = before true

console.log('isvalidEmail', isValidEmail); = isvalidEmail true


I'm trying to get isValidEmail to be true when it hits the first true at [email protected]

Why am I not getting this result?


Solution

  • Try change this if (every(isValidEmailArray, Boolean)) {

    to this: if (every(newIsValidEmailArray, Boolean)) {

    You are still referencing the old state.


    This line will still be false unless you put it inside another callback from setState: console.log('isvalidEmail', isValidEmail);

    The call to setState is not 'instant': https://reactjs.org/docs/react-component.html#setstate