Skip to content
tezvyn:

React State Updates: The Queue and the Updater Function

Source: react.devHardHow cards are made

React State Updates: The Queue and the Updater Function

React batches state updates from one event, like a waiter taking a full order before heading to the kitchen. This prevents multiple re-renders. The footgun: setCount(count + 1) called three times only increments once, as count is fixed for that render.

Why it exists

Triggering a re-render for every single state change is inefficient. It can also lead to confusing, "half-finished" UIs where only some variables have updated. React batches state updates from a single event to improve performance and ensure UI consistency by rendering only the final result.

The mental model

Think of React as a waiter at a restaurant. A waiter doesn't run to the kitchen after you order your first dish. Instead, they take your complete order, let you make changes, and even take orders from others at the table before making a single trip. React does the same: it collects all state update requests within an event handler before processing them and triggering a single re-render.

How it works

When you call a state setter like setNumber(number + 1), you're telling React to replace the state with a new value. If you call this three times in one click handler, you're not incrementing three times. Because state is a fixed snapshot for that render, the number variable is the same in all three calls. You're effectively calling setNumber(0 + 1) three times, and the final state is 1.

To solve this, you pass an "updater function" instead of a value, like setNumber(n => n + 1). This tells React to "do something with the current state value" rather than just replacing it. React queues these functions. During the next render, it processes the queue in order, passing the result of one function as the input to the next.

When to use it

Use an updater function whenever you need to update a state variable multiple times within a single event, or when the next state depends on the previous state in the update queue. It's the safe and correct way to handle sequential updates to the same piece of state.

When not to use it

Passing a direct value like setNumber(42) is perfectly fine for most cases, especially when the new state doesn't depend on the old state, or when you're only setting state once per event. React's batching is scoped to a single synchronous event; it does not batch updates across separate events, like two distinct button clicks.

One canonical example

Imagine a button that should increment a counter by 3. The wrong approach is setNumber(number + 1); setNumber(number + 1); setNumber(number + 1);. This will only increment the counter to 1. The correct approach uses updater functions: setNumber(n => n + 1); setNumber(n => n + 1); setNumber(n => n + 1);. This correctly queues three increment operations, resulting in the counter becoming 3.

Interview question

In a React component, if setCount(count + 1) is called three times within a single event handler, why does the counter only increment by one?

  • a.Direct state updates are asynchronous, and the subsequent calls execute before the previous ones have finished updating the state.
  • b.React automatically optimizes sequential identical state updates, treating setCount(count + 1) as a single operation.
  • c.React's batching mechanism discards all but the final state update call within a single event.
  • d.The 'count' variable inside the event handler holds a fixed value from the render, making all three calls update from the same initial state.Correct
Why?

The card explains that 'state is a fixed snapshot for that render,' meaning all three calls to setCount(count + 1) use the same initial 'count' value. Option C is incorrect because batching processes updates, it doesn't discard them; the issue is how the 'count' value is captured.

Just read this? Test yourself on what you have been reading.

Read the original → react.dev

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on react — each one lists the topics its interview covers.

See open roles