🧭 Introduction
As React applications grow, managing complex state using multiple useState hooks becomes confusing and error-prone. When state logic includes multiple values, actions, and updates, React provides a powerful alternative called the useReducer hook.
In this lesson, you will learn:
- What
useReduceris - Why it is better than
useStatein complex scenarios - How
useReducerworks internally - A real-world example
- Best practices and FAQs
❓ What is useReducer Hook?
useReducer is a React hook used for state management based on actions.
In simple words:
useReducermanages state using a reducer function, similar to Redux but built into React.
🧠 When Should You Use useReducer?
✅ When state logic is complex
✅ When multiple state values are related
✅ When state updates depend on previous state
✅ When you want predictable state changes
❌ Not needed for simple counters or input fields
🔄 useState vs useReducer
| Feature | useState | useReducer |
|---|---|---|
| State complexity | Simple | Complex |
| Multiple state values | Difficult | Easy |
| Logic separation | ❌ | ✅ |
| Predictability | Medium | High |
| Redux-like pattern | ❌ | ✅ |
🧩 How useReducer Works (Concept)
useReducer is based on three core parts:
1️⃣ State – current data
2️⃣ Action – what happened
3️⃣ Reducer – how state changes
🧠 Basic Syntax of useReducer
const [state, dispatch] = useReducer(reducer, initialState);
state→ current statedispatch→ sends actionreducer→ function that updates state
🛠 Simple Example: Counter with useReducer
📄 Counter.jsx
import { useReducer } from "react";
const initialState = { count: 0 };
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, initialState);
return (
<>
<h2>Count: {state.count}</h2>
<button onClick={() => dispatch({ type: "INCREMENT" })}>+</button>
<button onClick={() => dispatch({ type: "DECREMENT" })}>−</button>
<button onClick={() => dispatch({ type: "RESET" })}>Reset</button>
</>
);
};
export default Counter;
🧠 What’s Happening Here?
✔ UI dispatches an action
✔ Reducer decides how state changes
✔ New state is returned
✔ Component re-renders
This makes state changes predictable and structured.
🏗 Real-World Example: Authentication State
🎯 Problem
Manage login, logout, and loading states cleanly.
📄 authReducer.js
export const initialAuthState = {
user: null,
isAuthenticated: false
};
export const authReducer = (state, action) => {
switch (action.type) {
case "LOGIN":
return {
user: action.payload,
isAuthenticated: true
};
case "LOGOUT":
return {
user: null,
isAuthenticated: false
};
default:
return state;
}
};
📄 AuthContext.jsx (useReducer + Context)
import { createContext, useReducer } from "react";
import { authReducer, initialAuthState } from "./authReducer";
const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [state, dispatch] = useReducer(authReducer, initialAuthState);
const login = (user) => dispatch({ type: "LOGIN", payload: user });
const logout = () => dispatch({ type: "LOGOUT" });
return (
<AuthContext.Provider value={{ state, login, logout }}>
{children}
</AuthContext.Provider>
);
};
export default AuthContext;
🚀 Why useReducer is Powerful
✔ Centralized state logic
✔ Clear action-based updates
✔ Easier debugging
✔ Scales better than useState
⚠ Common Mistakes
❌ Mutating state directly
❌ Forgetting default case in reducer
❌ Using useReducer for very simple state
❌ Writing complex logic inside components
🎯 Best Practices
✅ Keep reducer functions pure
✅ Use constants for action types
✅ Combine useReducer with Context API
✅ Split reducers for large apps
❓ FAQs — useReducer Hook
🔹 Is useReducer better than useState?
Not always. useReducer is better only when state logic is complex.
🔹 Is useReducer similar to Redux?
Yes, it follows the same reducer + action pattern, but without external libraries.
🔹 Can I use useReducer with Context API?
Yes! This is a very common real-world pattern.
🔹 Does useReducer improve performance?
It improves code organization and predictability, not raw performance.
🔹 Should beginners learn useReducer?
Yes, after understanding useState and Context API.
🧠 Quick Recap
✔ useReducer manages complex state
✔ Uses reducer + action pattern
✔ Ideal for authentication & forms
✔ Works perfectly with Context API
🎉 Conclusion
The useReducer hook is a powerful state management tool in React that brings structure, predictability, and scalability to your applications. When combined with Context API, it forms the foundation of professional-grade React state management.
After mastering useReducer, you’re ready for advanced patterns used in real projects 🚀
👉 Next Lesson (SECTION 5):
Lesson 28 — useReducer + Context API (Complete State Management Pattern)