Why useState Doesnât Update Immediately (And Why Thatâs a Good Thing)
useState doesnât update values immediately. Instead, React schedules updates, batches multiple changes, and applies them in the next render. This is why repeated updates using the same state value can feel inconsistent, and why the functional update form (prev => ...) is often needed to get the correct result.
One of the first confusing moments in React usually comes from something that looks completely normal.
You write this:
setCount(count + 1);
console.log(count);And you expect the updated value.
But instead, you still get the old one.
At that point, it feels like:
âstate is asynchronousâ
Which is not entirely wrongâbut also not the full picture.
Whatâs Actually Happening
When you call setCount, React doesnât immediately change the value.
Instead, it does something else:
- it queues the update
- waits
- then re-renders the component
So inside the same render, nothing changes yet.
The new value only exists in the next render.
Thinking in Renders Instead of Variables
This is where the mental shift happens.
Each render has its own snapshot of state.
// Render 1
count = 0
// Render 2
count = 1When you call:
setCount(count + 1);Youâre not updating the current value.
Youâre telling React:
âNext time you render, use this new valueâ
Why This Code Only Adds Once
setCount(count + 1);
setCount(count + 1);At first glance, it looks like it should add twice.
But both lines are using the same snapshot:
count = 0So React sees:
setCount(1);
setCount(1);And the final result becomes:
count = 1The Role of Functional Updates
To fix this, React provides another form:
setCount(prev => prev + 1);
setCount(prev => prev + 1);Here, prev is not tied to the render.
It represents the latest value at the moment React processes the updates.
So React evaluates it step by step:
- first update â 0 â 1
- second update â 1 â 2
Now the final result becomes:
count = 2Batching: Why React Doesnât Re-render Twice
Another surprising behavior is this:
Even if you call multiple updates, React usually renders only once.
setCount(c => c + 1);
setName("John");You might expect two renders.
But React does this instead:
- queue both updates
- calculate the final state
- render once
Why React Works This Way
If React rendered after every update, it would be inefficient.
Instead of:
update â render
update â renderReact batches them:
update
update
render onceThis keeps your app faster and more predictable.
Putting It All Together
There are two key ideas behind this behavior:
- State updates are scheduled, not immediate
- Multiple updates are batched into a single render
And the difference between these two lines:
setCount(count + 1);and
setCount(prev => prev + 1);comes down to when the value is read.
A Better Way to Think About It
Instead of thinking:
âI am changing the valueâ
Think:
âI am requesting a new render with updated stateâ
Final Takeaway
State in React is not like a normal variable.
It doesnât change instantly, and it doesnât belong to the current execution.
It belongs to the next render.
Once you see it this way, behaviors that once felt confusing start to feel completely logical.