-1

I have an event handler on a button in React.

The component that holds button takes in a prop: userInput, from an input field in the parent.

Then it uses this to update the state: bLength. When I console.log bLength, it is the old value. Also, I've tried setTimeout to 3000ms and it runs immediately.

handleClick = e => {
    var { userInput } = this.props;
    this.setState(() => ({
      bLength: userInput,
    }));
    console.log(this.state.bLength);
    setTimeout(console.log(this.state.bLength), 3000);
  }
};

State of bLength is initially set to 3.
User inputs 6
User clicks button
Console logs 3
User clicks button AGAIN
Console logs 6.

I thought passing a function to setState eliminates the problem of setState's async uncertainty.

Why is this happening?

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
nakji
  • 81
  • 7
  • If you would like to read about the why, [here is a highly voted question & answer](https://stackoverflow.com/questions/36085726/why-is-setstate-in-reactjs-async-instead-of-sync) or you can refer to the [React docs](https://reactjs.org/docs/react-component.html#setstate). – Michael Cheng Aug 08 '19 at 17:39

1 Answers1

2

setState is asynchronous, to correctly access the most recent value, use the second argument which takes a callback to execute after the update.

handleClick = e => {
    var { userInput } = this.props;
    this.setState(() => ({
      bLength: userInput,
    }), () => console.log(this.state.bLength));

  }
};

setTimeout requires a callback, you're just executing it immediately:

setTimeout(() => console.log(this.state.bLength), 3000);
Dupocas
  • 20,285
  • 6
  • 38
  • 56