Capítulo 33 de 116
Combining a reducer (Ch 31) with Context (Ch 32) lets any component in a subtree both read shared state and dispatch updates to it, without prop-drilling either the state or the dispatch function through every intermediate layer.
dispatch function into two separate Context objects (e.g. TasksContext and TasksDispatchContext) — components that only need to read state subscribe to one; components that only need to dispatch actions subscribe to the other, so a component that only dispatches doesn't re-render when the state itself changes.useReducer once, then wraps its subtree in both providers, passing tasks to one and dispatch to the other — every descendant can now reach either via useContext, however deeply nested.useContext(TasksContext) to read the list, or useContext(TasksDispatchContext) to get dispatch and fire actions — neither requires any prop passed through components in between.useTasks(), useTasksDispatch()) into a single dedicated module — consumers then import a clean Hook API instead of importing raw Context objects and calling useContext themselves everywhere.// tasks-context.js — the "wiring into a single file" pattern
const TasksContext = createContext(null);
const TasksDispatchContext = createContext(null);
export function TasksProvider({ children }) {
const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);
return (
<TasksContext value={tasks}>
<TasksDispatchContext value={dispatch}>
{children}
</TasksDispatchContext>
</TasksContext>
);
}
export function useTasks() { return useContext(TasksContext); }
export function useTasksDispatch() { return useContext(TasksDispatchContext); }
useTasks()/useTasksDispatch() instead of raw Context plumbing.useTasks()/useTasksDispatch() API, hiding the Context machinery entirely.useTasks()/useTasksDispatch() wrapper pattern generalized.