Functional State Updates

Functional state updates compute the next state from the previous state rather than from a value captured in the current render. They are especially useful when multiple updates may be queued or when the next value depends on the previous one.

In React, a state setter such as `setCount` can receive either a value or a function. When it receives a function, React calls that function with the latest pending state and uses its return value as the next state. This is commonly called an updater function.

Use a functional update whenever the new state depends on the old state. For example, `setCount(count => count + 1)` expresses "take the current pending count and add one," whereas `setCount(count + 1)` computes the value from the `count` variable available in the current render.

This distinction matters when several updates are queued before React renders again. Multiple value-based updates can be derived from the same render snapshot, while updater functions can be applied in sequence so each calculation receives the result produced by the previous update.

Functional updates also make state transitions less dependent on a particular render's captured values. They do not make arbitrary side effects safe or remove the need to understand React's rendering and batching behavior; they specifically solve the problem of deriving state from previous state.

Key points

Interview questions

Should you always use functional updates for React state?

No. A direct value is often clearer when the new state does not depend on the old state, such as `setOpen(true)`. The functional form is most useful when the calculation reads the previous state, such as toggling a boolean or incrementing a counter. The important rule is to make the dependency explicit rather than using an updater mechanically.

What is a functional state update in React, and when would you use one?

A functional state update passes a function to the state setter, such as `setCount(c => c + 1)`. React gives that function the pending state value, and the function returns the next state. I use it whenever the next state depends on the previous state. It is particularly useful when several updates may be queued before React renders again.

What is the difference between `setCount(count + 1)` and `setCount(c => c + 1)`?

The first form calculates a value using `count` from the current render. The second passes a function that React can call with the pending state. If several updates are queued, repeated value-based expressions can all be based on the same render value, while updater functions can build on one another. Therefore the functional form is the safer expression when each update depends on the result of the previous update.

What happens when several functional updates are queued for the same state variable?

React queues the updater functions and applies them to the pending state in order. Each updater receives the state produced by the preceding update. For example, three `c => c + 1` updates starting from 0 produce 1, then 2, then 3. This lets multiple dependent transitions compose without relying on a stale value from the current render.

Why are functional updates relevant when thinking about concurrent rendering?

Concurrent rendering means React may start, pause, resume, or discard rendering work before committing a result. Code should therefore describe state transitions in terms of the state React is processing rather than assuming a particular render's captured value is the authoritative next state. An updater function provides React with a state transition that can be applied to the appropriate pending state. This makes the dependency on previous state explicit and avoids coupling the calculation to one render snapshot.