JAVASCRIPT
Managing Complex Component State with React's useReducer Hook
Implement predictable state management for complex state logic in React using the useReducer hook, ideal for situations beyond simple boolean toggles.
import React, { useReducer } from 'react';
// 1. Define the reducer function
// It takes the current state and an action, and returns the new state
const counterReducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
case 'RESET':
return { count: action.payload }; // payload could be the initial value
default:
return state;
}
};
function ComplexCounter() {
// 2. Initialize useReducer
// `state` is the current state object ({ count: ... })
// `dispatch` is a function to send actions to the reducer
// `counterReducer` is the reducer function
// `{ count: 0 }` is the initial state
const [state, dispatch] = useReducer(counterReducer, { count: 0 });
return (
<div style={{ padding: '20px', border: '1px solid #ccc', borderRadius: '8px' }}>
<h1>Counter: {state.count}</h1>
<button onClick={() => dispatch({ type: 'INCREMENT' })} style={{ marginRight: '10px', padding: '10px' }}>
Increment
</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })} style={{ marginRight: '10px', padding: '10px' }}>
Decrement
</button>
<button onClick={() => dispatch({ type: 'RESET', payload: 0 })} style={{ padding: '10px' }}>
Reset
</button>
</div>
);
}
How it works: The `useReducer` hook is an alternative to `useState` for managing more complex state logic that involves multiple sub-values or when the next state depends on the previous one. It takes a reducer function and an initial state, returning the current state and a `dispatch` function. The `dispatch` function accepts an 'action' object, which describes 'what happened'. The reducer function then processes this action to compute and return the next state, making state transitions more predictable and easier to test compared to multiple `useState` calls.