Reducers and Context
Centralize complex state transitions and provide shared values to distant descendants.
A reducer describes state transitions as actions. Context provides a value to descendants without passing it through every intermediate component.
Move transitions into a reducer
progress.tsx
function reducer(state, action) {
switch (action.type) {
case "completed": return { ...state, completed: [...state.completed, action.lesson] };
case "reset": return initialState;
default: throw new Error(`Unknown action: ${action.type}`);
}
}
const [state, dispatch] = useReducer(reducer, initialState);
Reducers must be pure. Actions describe what happened; the reducer determines the next state.
Provide shared state
CourseProvider.tsx
const CourseContext = createContext(null);
<CourseContext value={{ state, dispatch }}>{children}</CourseContext>
Consume with useContext and fail clearly when the provider is missing. Split frequently changing contexts when unrelated consumers rerender too broadly.
Keep this
Use reducers for complex transitions, context for genuinely shared values, and keep both APIs narrow.
Your place is saved on this device.