Open In App

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?

Example: Below is an example of combining useContext with useReducer.






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:

Output




Article Tags :