React | useReducer: When useState Starts Getting Messy

I usually reach for useState by default, but when the state logic starts feeling a bit tangled—or I’ve got multiple values changing together—I’ve been reaching for useReducer. It’s like a mini state machine right inside your component.
✅ Quick Example: A Basic Counter
This is a super simple example, just to show how it works.
import { useReducer } from 'react';
// reducer function
const reducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
case 'RESET':
return { count: 0 };
default:
return state;
}
};
const Counter = () => {
const [state, dispatch] = useReducer(reducer, { count: 0 });
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;
💡 Why Even Bother?
For simple stuff, useState is totally fine. But useReducer starts to shine when:
- You’ve got a few related pieces of state
- You’re passing around logic for how to update them
- You just want to keep your state logic in one place
Honestly, I find it keeps things tidier once you’ve got more than one or two state updates bouncing around.
💭 Where I Use It
I’ve used it for things like form state, toggles, and especially anything where the logic feels more like “if this, then that”. Not always necessary—but good to have in the toolbox.
🚀 Hope this makes things a bit clearer for someone else on the same journey.
Subscribe to my newsletter
Read articles from Valencia Miyeon Jang directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Valencia Miyeon Jang
Valencia Miyeon Jang
Front-end developer with a background in Korean language QA and education.Experienced in localisation testing, cross-functional teamwork, and user-focused development.I enjoy crafting intuitive web experiences with React, Next.js, and TypeScript — always learning, always building.