Suggest an editImprove this articleRefine the answer for “What is the "Context + Reducer" pattern?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**"Context + Reducer"** is a pattern that combines **Context** (for global access to data) and **useReducer** (for predictable state management through actions). **Key point:** Context is "a way to share state", and the reducer is the "brain" that says *how* the state changes.Shown above the full answer for quick recall.Answer (EN)Image## The essence of the pattern > We combine **Context** (for global access to data) > and **useReducer** (for predictable state management through actions). Context is "a way to share state". The reducer is the "brain" that says *how* the state changes. --- ## Basic idea ```javascript // Context: available to all components const CounterContext = createContext(); // Reducer: manages state changes function counterReducer(state, action) { switch (action.type) { case "increment": return { count: state.count + 1 }; case "decrement": return { count: state.count - 1 }; default: throw new Error("Unknown action"); } } ``` --- ## Implementing the pattern ### 1. Provider (wraps the whole app) ```javascript function CounterProvider({ children }) { const [state, dispatch] = useReducer(counterReducer, { count: 0 }); return ( <CounterContext.Provider value={{ state, dispatch }}> {children} </CounterContext.Provider> ); } ``` --- ### 2. Using it in components ```javascript function CounterDisplay() { const { state } = useContext(CounterContext); return <p>Count: {state.count}</p>; } function CounterButtons() { const { dispatch } = useContext(CounterContext); return ( <> <button onClick={() => dispatch({ type: "decrement" })}>-</button> <button onClick={() => dispatch({ type: "increment" })}>+</button> </> ); } ``` --- ### 3. Wrapping the app ```javascript function App() { return ( <CounterProvider> <CounterDisplay /> <CounterButtons /> </CounterProvider> ); } ``` --- ## What happens "under the hood" 1. `useReducer` manages the local state. 2. `Context.Provider` makes `{ state, dispatch }` available globally. 3. Any component in the tree can: - read the current state through `useContext(Context).state`; - change it through `dispatch({ type: "..." })`. --- ## Why this is convenient | Advantage | Description | |---|---| | Predictability | All changes are centralized through the `reducer` | | Global availability | Through Context the state is available to the whole tree | | Scalability | You can create many isolated "stores" | | Simplicity | No need for Redux, Redux Toolkit, Zustand, etc. | | Testability | The `reducer` is a pure function, easy to test | | Encapsulation | State is managed strictly through `dispatch` | --- ## Advanced version (splitting state and dispatch) To **avoid unnecessary re-renders**, contexts are often **split**: ```javascript const StateContext = createContext(); const DispatchContext = createContext(); function CounterProvider({ children }) { const [state, dispatch] = useReducer(counterReducer, { count: 0 }); return ( <DispatchContext.Provider value={dispatch}> <StateContext.Provider value={state}>{children}</StateContext.Provider> </DispatchContext.Provider> ); } // now consumers of state and dispatch are independent: function useCounterState() { return useContext(StateContext); } function useCounterDispatch() { return useContext(DispatchContext); } ``` Now a change to `state` does not cause a re-render in components that are subscribed only to `dispatch`. --- ## Where it's used - Auth: login/logout/token - Theme: dark/light theme - Cart: e-commerce cart - UI: modals, alerts, loaders - Form Wizard: transitions between steps --- ## Summary | What it gives you | How it's implemented | |---|---| | Global access to state | Context | | Predictable updates | useReducer | | Centralized logic | reducer functions | | Simple architecture without Redux | combining Context + Reducer | --- **Conclusion:** > "Context + Reducer" is a mini-Redux built into React: > simple, clean, and a perfect fit for medium-complexity applications.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.