Hooks

useState: batching & immutability

Functional updates, batching, lazy init, and derived-state pitfalls.

intermediate All levels

useState stores state that survives re-renders. The setter schedules a re-render; React batches multiple updates in the same event into one render for performance.

State updates are like mailing edits to a printer: batch several into one envelope, and always describe the change relative to the last copy, not the copy you remember.

Key concepts

1
Because updates are batched and the closure captures a stale value, use the functional form setCount(c => c + 1) when the next value depends on the previous. For expensive initial values, pass a lazy initializer function so it runs only once.
functional formlazy initializersetCount(c => c + 1)
2
State must be treated as immutable — spread into a new object/array; mutating in place skips the re-render because the reference is unchanged.
immutable
3
Pitfall — derived state: copying a prop into state and never syncing it. Prefer computing during render or useMemo. Interview angle: "why did two setCount(count+1) calls only increment once?" — both read the same stale count; the functional updater fixes it.
Pitfall — derived state:Interview angle:useMemosetCount(count+1)count