Functional Updates
Last updated: 2026-11-02
Functional Updates Functional Updates
Passing a function to setState, such as setCount(c => c + 1), means computing the next state from the latest previous value. When several updates run in the same event, or when state is read inside an asynchronous closure such as a timer, this form is required to avoid working with a stale value. The difference is invisible in simple cases and decisive in the tricky ones.
| Group | Rendering & State |
|---|---|
| Kind | Pattern |
| Since | React 16.8 |
ℹ️ Info The editor transpiles JSX to JavaScript and renders the real UI in a sandbox; components mount automatically — no manual render call needed.
📝 Syntax
setCount((prev) => prev + 1) // ✅ based on the latest value, safe to call repeatedly
setCount(count + 1) // ❌ a stale closure value, lost during batched updates
⚙️ Parameters
| updater (update function) | A pure function that receives the latest state value and returns the next one; it must be free of side effects because React may call it several times. |
|---|
Returns:No return value — a coding convention and mental model.
▶ Example
The example runs out of the box: it auto-renders when expanded, and edits take effect instantly.
Output:
Two counters with a button each: clicking "Functional +3" adds exactly three, while the "Direct value" button only adds one per click because the batched updates overwrite each other — the difference between the two styles is obvious at a glance.
💡 Key Points
⚠️ Warning Several set calls inside one event handler are batched: with a direct value only the last one survives, while functional updates always build on the previous value.
💡 Tip Inside asynchronous code such as setTimeout or promise callbacks the captured state is always stale, so use functional updates there.
ℹ️ Info The updater must be a pure function: React may call it more than once in concurrent mode to verify the result, and side effects would then break.
🏷️ More Rendering & State
💡 Related Cases
More case studies coming soon.
📚 Related Tutorials
❓ FAQ
Q What is the difference between setCount(count + 1) and setCount(c => c + 1)?
A The first uses the stale value from the current render closure, so batched updates overwrite each other; the second queues the updates and computes each one from the latest previous value, so the result is always correct.
Q Why did three consecutive setState calls only add one?
A All three setCount(count + 1) calls read the same old value, and React batches them into one, so only the last one counts. Using setCount(c => c + 1) three times adds three.
Q Why is the state value wrong when I update it inside setTimeout?
A The timer callback closes over the state as it was when the timer was created. Use a functional update such as setX(prev => ...), or rebuild the timer whenever its dependencies change.