useReducer with Context API
Use useReducer in conjunction with React's Context API to manage and distribute complex application state across multiple components.
// State management using useReducer with Context API
// Reducer function to handle state changes based on action type
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
// Create context
const CountContext = React.createContext();
// Context Provider component using useReducer hook
function CountProvider({ children }) {
const [state, dispatch] = React.useReducer(reducer, initialState);
return (
<CountContext.Provider value={{ state, dispatch }}>
{children}
</CountContext.Provider>
);
}
// Custom hook to use the context
function useCount() {
const context = React.useContext(CountContext);
if (!context) {
throw new Error('useCount must be used within a CountProvider');
}
return context;
}
The code represents a simple counter application state managed with useReducer and the React Context API. It includes an initial state, a reducer function to manage state changes, a context for passing down state, a provider component which encapsulates the useReducer hook, and a custom hook to consume the context in child components.
// Component that displays the count
function CountDisplay() {
const { state } = useCount();
return <div>{state.count}</div>;
}
This piece of code provides a CountDisplay component, which uses the custom hook useCount to access the count state and then renders it.
// Component that provides buttons to increment or decrement the count
function CounterControls() {
const { dispatch } = useCount();
return (
<div>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
This code snippet shows a CounterControls component, which uses the custom hook useCount to dispatch actions for incrementing or decrementing the count state.
// App component that uses CountProvider to wrap the components that need access to the count state
function App() {
return (
<CountProvider>
<CountDisplay />
<CounterControls />
</CountProvider>
);
}
This is the App component which uses the CountProvider to wrap other components such as CountDisplay and CounterControls, enabling them to access the context state and dispatch actions.