useState → useReducer: the evolution
useState gives you one value and one setter. When state logic grows —
multiple fields, conditional updates, action-driven transitions — N independent setters
become spaghetti. useReducer centralizes all transitions in ONE pure function:
reducer(state, action) → newState. You call
dispatch({{type:'ADD', text:'Learn React'}}) and the reducer decides what happens.
| piece | role | analogy |
|---|---|---|
reducer |
pure function: (state, action) → newState | the gearbox — receives a gear shift, outputs new speed |
dispatch |
sends an action to the reducer | the gear shift — you don't change gears directly, you request a shift |
action |
plain object: {{type, ...payload}} |
the shift instruction — "shift up", "shift down" |
initialState |
the starting state | neutral gear — where you begin |
1 · the reducer you write (edit me)
2 · Babel compiles JSX → element tree
<TodoApp/> becomes React.createElement(TodoApp).
Each dispatch() calls the reducer, React gets the new state, re-renders.
// (hit "compile & render" to see Babel's output)
3 · live React (the dispatch model, proven)
Click "Add" to dispatch {'{type:"ADD"}'}, click a todo to dispatch
{'{type:"TOGGLE"}'}, click ✕ to dispatch {'{type:"DELETE"}'}.
The gold-check does this automatically: 3× Add, toggle item 1,
delete item 1 → asserts the reducer handled every action correctly.
items: — · gold: 3× Add → toggle → delete → expect 2 items, 0 done
intent → pattern
| intent | pattern | why |
|---|---|---|
| add an item | case 'ADD': return [...state, newItem] |
immutable spread — never .push() |
| update one item | state.map(t => t.id === id ? {...t, done: !t.done} : t) |
map returns a new array; spread copies the matched item |
| remove an item | state.filter(t => t.id !== id) |
filter returns a new array without the removed item |
| reset everything | case 'CLEAR': return [] |
or remount with a new key to wipe all state |
| multi-field state | {count:0, step:1, status:'idle'} + action-driven transitions |
one reducer replaces N setters — all transitions in one place |