One of the most common questions developers ask when working with React Hooks is:
Should I use
useStateoruseReducer?
Both hooks are used to manage state in functional components, but they serve different purposes based on complexity, structure, and how you plan to update the state.
Let’s break it down with real-world examples and when to use each.
⚡ useState — Simple and Straightforward
useState is the most commonly used hook for handling local state.
✅ Best For
- Simple states like strings, numbers, and booleans
- Independent values (not tightly related)
- Quick reads and updates
📦 Example
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}
Here, count is just a number — easy to update with setCount.
🧠 useReducer — For Complex or Structured State
useReducer is perfect when your state is complex, deeply nested, or when multiple actions affect it. It’s similar to how reducers work in Redux.
✅ Best For
- Managing related pieces of state
- Handling multiple actions
- Complex state logic (e.g., form validation, state transitions)
📦 Example
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 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
<h2>Count: {state.count}</h2>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</>
);
}
Instead of calling a setter, you dispatch an action and let the reducer decide what to do.
🆚 useState vs useReducer: Head-to-Head Comparison
| Feature | useState |
useReducer |
|---|---|---|
| Syntax | Simple, direct updates | Structured, via reducer |
| State Complexity | Low | Medium to High |
| Multiple Values | Separate useState calls |
Single reducer with one state object |
| Best For | UI toggles, counters, inputs | Forms, workflows, multi-step states |
| Code Maintainability | Easy for small components | Better for growing logic |
| Performance Optimization | Basic | Supports advanced patterns |
🚦 When Should You Use useReducer Instead of useState?
Use useReducer if
- You have multiple related states (e.g. name, email, password).
- You want to use actions and switch cases for updates.
- You’re doing complex state transitions (e.g.,
OPEN,LOADING,SUCCESS,ERROR). - You plan to scale or refactor the state logic later.
Otherwise, stick with useState for quick and simple state handling.
🧩 Bonus Tip: You Can Combine Both!
Sometimes, using both makes sense. Use useReducer for the heavy lifting and useState for UI toggles or temporary flags.
✅ Conclusion
To summarize
- 🧵 Use
useStatefor a simple, isolated state. - 🧶 Use
useReducerfor a complex, related state with multiple transitions.
💡 Think of
useStatelike a notepad — quick and handy.Think of
useReducerlike a spreadsheet — organized and scalable.

Join the conversation! Your thoughts help the community grow.