useReducer or Redux Reducer? How to Tell Which You Need
Source: Dev.to

🎯 The Core Idea: What’s a Reducer?
Both useReducer and Redux reducers are built on the same concept: a reducer is just a function that:
- Takes the current state and an action
- Returns the next state
In plain JavaScript, it looks like this:
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
No side effects. No mutations. Just a pure function.
🪝 useReducer in React
useReducer is a React hook for managing state in a single component (or a small group of components via props or context).
Example
import React, { useReducer } from 'react';
function Counter() {
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;
}
}
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
dispatch({ type: 'increment' })}>+
dispatch({ type: 'decrement' })}>-
);
}
Key points about useReducer
- State is local to the component (unless you manually share it via context)
- No middleware, no dev tools, no global store
- Great for complex local state updates
🏪 Redux Reducers
In Redux, a reducer works the same way — but instead of local state, it updates a global store that can be accessed anywhere in your app.
Reducer definition
// reducer.js
function counterReducer(state = { count: 0 }, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
export default counterReducer;
Store creation
// store.js
import { createStore } from 'redux';
import counterReducer from './reducer';
const store = createStore(counterReducer);
Component usage
// Component.jsx
import { useSelector, useDispatch } from 'react-redux';
function Counter() {
const count = useSelector(state => state.count);
const dispatch = useDispatch();
return (
<>
Count: {count}
dispatch({ type: 'increment' })}>+
dispatch({ type: 'decrement' })}>-
);
}
Key points about Redux reducers
- State is global
- Supports powerful middleware (like Redux Thunk, Redux Saga)
- Integrated with dev tools for debugging
- Usually used in large, complex apps
🔍 How They’re the Same

Both are built on the same reducer concept from functional programming.
🔀 How They’re Different

💡 Which Should You Use?
Use useReducer when
- The state is complex, but only relevant to one component or a small subtree.
- You don’t need global state sharing.
- You want to avoid pulling in Redux for something small.
Use Redux reducers when
- You need global state management.
- You want advanced debugging, time‑travel, and middleware.
- Your app is big enough to justify the extra setup.
🏁 Final Takeaway
useReducer and Redux reducers are like bicycles and buses — they both get you from state A to state B, but one is for short, personal trips (local component state), and the other is for carrying the whole city (global app state). They share the same functional programming DNA, but live in different ecosystems.