Summary
Never mutate state in place — spread, Immer produce, or persistent data structures. React state updates rely on reference change for re-render detection. Mutating nested objects without new root reference → silent no-op updates. Same rule for context values and reducer state.
Code example
function addTodo(todos, text) {
return [...todos, { id: crypto.randomUUID(), text, done: false }];
}
function toggleTodo(todos, id) {
return todos.map((t) => (t.id === id ? { ...t, done: !t.done } : t));
}
Key points
- Never mutate state in place — spread, Immer produce, or persistent data structures.
- React state updates rely on reference change for re-render detection.
- Mutating nested objects without new root reference → silent no-op updates.
- Same rule for context values and reducer state.