🧠 useState vs useReducer in React
Imagine you’re organizing your room. You have a few things to manage: your books, clothes, and gadgets. If you only have one or two items, it’s easy. But if your room is full of stuff, you need a system.
Get Mukesh Dani’s stories in your inbox
Join Medium for free to get updates from this writer.
That’s exactly how state management works in React. Let’s dive in!
🧺 Meet useState: The Simple Basket
useState is like a small basket. You put one item in it — maybe your name, a number, or a toggle (like ON/OFF). It’s perfect when things are simple.
🧃 Example:
const [name, setName] = useState("John");
<input onChange={(e) => setName(e.target.value)} />✅ Easy.
✅ Clean.
✅ Perfect for small tasks.
😵 When useState Becomes a Problem
Let’s say you’re building a form with:
- Name
- Password
- City
- Address
With useState, you’d write:
const [name, setName] = useState('');
const [password, setPassword] = useState('');
const [email, setEmail] = useState('');
const [city, setCity] = useState('');
const [address, setAddress] = useState('');And for each input:
<input onChange={(e) => setName(e.target.value)} />
<input onChange={(e) => setPassword(e.target.value)} />
...😩 Problems:
- Too many variables and functions.
- Repetitive code.
- Hard to scale if you add more fields.
- Updating nested objects or arrays becomes messy.
🧠 Enter useReducer: The Smart Organizer
useReducer is like a smart drawer. You put everything inside one place, and use labels (called actions) to organize or update things.
Step 1: Define initial state
const emptyData = {
name: '',
password: '',
email: '',
city: '',
address: ''
};Step 2: Create a reducer function
const reducer = (state, action) => {
return { ...state, [action.type]: action.val };
};Step 3: Use the reducer in your component
const [state, dispatch] = useReducer(reducer, emptyData);Step 4: Update fields using dispatch
<input onChange={(e) => dispatch({ type: 'name', val: e.target.value })} />
<input onChange={(e) => dispatch({ type: 'password', val: e.target.value })} />
...✅ Full Working Example Using useReducer
import { useReducer } from "react";
const emptyData = {
name: '',
password: '',
email: '',
city: '',
address: ''
};
const reducer = (state, action) => {
return { ...state, [action.type]: action.val };
};
export default function UseReducerHook() {
const [state, dispatch] = useReducer(reducer, emptyData);
return (
<div>
<h4>useReducer Hook Example</h4>
<input type="text" placeholder="Enter name"
onChange={(e) => dispatch({ type: 'name', val: e.target.value })} />
<br /><br />
<input type="text" placeholder="Enter password"
onChange={(e) => dispatch({ type: 'password', val: e.target.value })} />
<br /><br />
<input type="text" placeholder="Enter email"
onChange={(e) => dispatch({ type: 'email', val: e.target.value })} />
<br /><br />
<input type="text" placeholder="Enter city"
onChange={(e) => dispatch({ type: 'city', val: e.target.value })} />
<br /><br />
<input type="text" placeholder="Enter address"
onChange={(e) => dispatch({ type: 'address', val: e.target.value })} />
<br /><br />
<ul>
<li>Name: {state.name}</li>
<li>Password: {state.password}</li>
<li>Email: {state.email}</li>
<li>City: {state.city}</li>
<li>Address: {state.address}</li>
</ul>
<button onClick={() => console.log(state)}>Add Details</button>
</div>
);
}🧩 Why useReducer is Better for Complex Forms
- ✅ One state object for all fields
- ✅ One function to update any field
- ✅ Easy to reset or debug
- ✅ Scales beautifully with more fields
🧠 Summary: When to Use What?
🎯 Final Thought
Start with
useStatewhen things are simple.
Switch touseReducerwhen things get messy.






