K. D.
K. D.

Reputation: 4249

Will setState complete before other events are handled?

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

Answers (3)

Shadab Ahmed
Shadab Ahmed

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

Retsam
Retsam

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

Bojan Ivanac
Bojan Ivanac

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

Related Questions