📖 Notes
LESSON 9 OF 18
useReducer — Complex State
State Logic That Outgrows useState
When state updates depend on multiple related actions — like a shopping cart with add, remove, and clear — useReducer centralises that logic instead of scattering it across many setState calls.
Reducer Pattern
State + Dispatch
🏗️
Structure
const [state, dispatch] = useReducer(reducer, initialState);
🔀
Reducer Function
A switch statement on action.type, returning the new state.
📤
Dispatching
dispatch({ type: "ADD", item: {...} });
🤔
When to Prefer
Multiple related updates, or next state depends on previous state non-trivially.
Shopping Cart Reducer
JSXimport { useReducer } from "react";
const init = { cart:[], total:0 };
function reducer(state, action) {
switch (action.type) {
case "ADD":
return { cart:[...state.cart, action.item], total:state.total+action.item.price };
case "REMOVE":
const item = state.cart.find(c => c.id===action.id);
return { cart:state.cart.filter(c => c.id!==action.id), total:state.total-(item?.price||0) };
case "CLEAR": return init;
default: return state;
}
}
function Cart() {
const [state, dispatch] = useReducer(reducer, init);
return (
<button onClick={() => dispatch({ type:"ADD", item:{id:1,name:"Python",price:0} })}>
Add Course
</button>
);
}