setState Doesn't Update the State Immediately: Here's the Fix

Something that all React developers learn sooner or later is that setState doesn’t update the state immediately - it’s asynchronous.

Why?

Because there’s a lot going on in the background with React trying to determine how to update and render UI as efficiently as possible. This involves things like batching operations that can update state (like setState).

The same goes for hooks like useState, which are also asynchronous, so that’s not a solution either.

That’s a big pain since you often want to take action based on a new state.

But there is a simple fix, and I’ll walk you through it quickly here.

Here’s a simple React component. When the div with content is clicked, it calls a function that updates the state.

I put a console.log statement before and after the setState call, and here’s what it prints to the console when invoked:

before setState false

after setState false

Hmm...That’s not what we want.

setState Takes 2 Inputs

While you typically only pass setState a single new object to merge with the previous state, you can also pass it a second input - a callback to run after the state is fully updated:

setState(newStateObject, [expression to run afterwards])

Typically the expression is a function.

So let’s move that second console.log statement to the second input of setState:

After re-rendering the component and clicking on the div, here’s what’s printed out:

before setState false

after setState true

That’s more like it!

In this case could just add console.log as the second argument, but typically you'll be doing at least a few operations with the new state, and need to encapsulate it in a function.