In React, useReducer
is a hook used to manage more complex state logic in functional components. It is an alternative to the useState
hook and is especially useful when:
- The state logic involves multiple sub-values.
- The next state depends on the previous one.
- You want to group state updates in a single place (like a reducer function).
If you’ve worked with Redux, useReducer
will feel familiar because it uses the same reducer pattern — where you describe how state changes in response to actions.
Syntax of useReducer
const [state, dispatch] = useReducer(reducer, initialState);
reducer
: A function that defines how the state should change.initialState
: The starting value for the state.state
: The current state value.dispatch
: A function used to send actions to the reducer.
Example: Counter Using useReducer
import React, { useReducer } from 'react';
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 };
case 'reset':
return initialState;
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<h2>Count: {state.count}</h2>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
<button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
</div>
);
}
export default Counter;
How useReducer
Works
- Initial Render: State is set to
initialState
. - Dispatching Actions: When you call
dispatch
, it sends anaction
object to thereducer
function. - Reducer Logic: Based on
action.type
, the reducer returns a new state. - Component Re-renders: React re-renders the component with the updated state.
Why Use useReducer
?
useReducer
is useful when:
- Your component has multiple state variables that depend on each other.
- You want to organize complex state logic in one place.
- You need a predictable and testable state transition.
useState
vs useReducer
Feature | useState | useReducer |
---|---|---|
Simple state | Best for simple values | Overkill for simple counters |
Complex logic | Hard to manage | Clean and structured |
Multiple states | Scattered across handlers | Centralized in one reducer function |
Performance | Fine for basic use | Can optimize with lazy init, etc. |
When to Prefer useReducer
- You have a form with many fields.
- You need to reset state to its initial value easily.
- You want to track previous states or undo changes.
- Your state updates are based on previous state values.
Pro Tip: Use with useContext
useReducer
is commonly used with useContext
to build global state management in React without Redux.
const MyContext = React.createContext();
function App() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<MyContext.Provider value={{ state, dispatch }}>
<MyComponent />
</MyContext.Provider>
);
}
Conclusion
The useReducer
hook is a powerful tool for managing state in React applications. It provides a structured way to handle complex state updates, making your components cleaner and more maintainable. If you find yourself writing multiple useState
calls or tangled update logic, give useReducer
a try!