How to combine useContext with useReducer?
Combining useContext
with useReducer
in React allows you to manage a global state more effectively by providing a centralized state management solution.
How to combine useContext with useReducer?
- Create a Context: First, you need to create a context to hold your global state and provide it to your component tree. You can use the
React.createContext()
function for this purpose. - Define a Reducer: Define a reducer function that specifies how state transitions should occur in response to dispatched actions. The reducer takes the current state and an action as arguments and returns the new state.
- Use
useReducer
Hook: Inside your component, use theuseReducer
hook to manage state transitions based on dispatched actions. This hook returns the current state and a dispatch function, which is used to send actions to the reducer. - Use
useContext
Hook: Use theuseContext
hook to access the state and dispatch function provided by the context.
Example: Below is an example of combining useContext with useReducer.
- We create a context called
GlobalStateContext
. - We define a reducer function that manages state transitions for a simple counter.
- We use the
useReducer
hook inside theGlobalStateProvider
component to manage the global state. - We provide the state and dispatch function to the context using
GlobalStateContext.Provider
. - We use
useContext
to access the state and dispatch function in theCounter
component. - Finally, we wrap our
Counter
component with theGlobalStateProvider
in theApp
component to make the global state available to it.
Javascript
import React, { createContext, useContext, useReducer } from 'react' ; // Step 1: Define a context const CounterContext = createContext(); // Step 2: Define a reducer function const reducer = (state, action) => { switch (action.type) { case 'increment' : return { count: state.count + 1 }; case 'decrement' : return { count: state.count - 1 }; default : return state; } }; /* Step 3: Create a component that provides the context and manages state with useReducer */ function CounterProvider({ children }) { const [state, dispatch] = useReducer(reducer, { count: 0 }); // Log the state whenever it changes console.log( 'Counter state:' , state); return ( <CounterContext.Provider value={{ state, dispatch }}> {children} </CounterContext.Provider> ); } // Step 4: Create a custom // hook to access the context function useCounter() { const context = useContext(CounterContext); if (!context) { throw new Error(`useCounter must be used within a CounterProvider`); } return context; } /* Step 5: Use the custom hook to access state and dispatch actions */ function Counter() { const { state, dispatch } = useCounter(); return ( <div> <h2>Counter: {state.count}</h2> <button onClick={ () => dispatch({ type: 'increment' }) }> Increment </button> <button onClick={ () => dispatch({ type: 'decrement' }) }> Decrement </button> </div> ); } function App() { return ( <CounterProvider> <Counter /> </CounterProvider> ); } export default App; |
Output: