Reputation: 4249
When setState()
is asynchronous, can we be sure, that this.state
is up to date in events that were fired afterwards? Simple example: a counter with two buttons. One button increments the counter, another button prints this.state
to the console. If we click "increase" and then "print" immediately, is it 100% guaranteed, that we will see the updated value or might it happen that the second event runs before setState
completes?
class Counter extends Component {
state = {counter: 0};
incCounter = () => this.setState(prevState => ({
counter: prevState.counter + 1
}));
logCounter = () => console.log(this.state.counter);
render = () => (
<div>
<button onClick={this.logCounter}>Log</button>
<button onClick={this.incCounter}>Inc</button>
</div>
);
}
Upvotes: 2
Views: 150
Reputation: 576
yes the second event can run and complete before setState
completes for first event. This is a possible situation and can happen if the window of firing events is in between2-4 ms
. If you want to get updated state always then you have to bind the function as a callback of setState
Upvotes: -1
Reputation: 33459
Technically, yes. setState
is asynchronous, and there's no guarantee that the state will have updated before the button is clicked.
... but in practice, we're talking about an window of about 2-4 milliseconds before the state is applied: that's not going to be a big enough window for a user interaction, like clicking a different button.
You can measure the size of this window yourself, using the second argument to setState, which executes when the state has been updated:
const start = Date.now();
this.setState(newState, () => {
const end = Date.now();
console.log(`Took ${end - start} ms to apply state`);
});
Upvotes: 2
Reputation: 1180
React prioritizes setState()
, but sometimes the new state will not be set when you expect it to.
If you want to be sure you are using the new state, right after using setState()
, you can use the callback function.
this.setState({
someState: true,
},() => {
console.log(this.state.someState); // Will be new state every time
});
Upvotes: 0