Chapter 2 · Practice 3 of 5
Update objects and arrays immutably
From State and data flow
Why it matters
React decides whether to re-render by comparing old and new state with Object.is. If you mutate an object or array in place and pass the same reference to the setter, React may skip the update, and memoized children show stale data.
Always create a new value:
| Mutating (avoid) | Returns a new value (prefer) |
|---|---|
push, index assignment | spread [...prev, x], with |
sort | toSorted |
reverse | toReversed |
| changing an item in place | map, filter |
When the next state depends on the previous one, use the updater form, for example setCount((c) => c + 1), so several updates in one event do not overwrite each other.
Do
- Use
toSorted,toReversedandwithinstead ofsort,reverseand index assignment - Use the updater function when the next state depends on the previous
Avoid
items.push(x); setItems(items)
Example
// Add, update and remove without mutation
setTodos((prev) => [...prev, newTodo]);
setTodos((prev) => prev.map((t) => (t.id === id ? { ...t, done: true } : t)));
setTodos((prev) => prev.filter((t) => t.id !== id));