useReducer
⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 2 min
useReducer
useReducer is a React Hook that lets you add a reducer to your component. It is an alternative to useState for managing complex state logic that involves multiple sub-values or when the next state depends on the previous one.
Concept: What is a Reducer?
If you are familiar with Redux, you already know how this works. A “reducer” is a pure function that takes the current state and an action, and returns the new state.
// A simple reducer function
function reducer(state, action) {
if (action.type === 'increment') {
return { count: state.count + 1 };
} else if (action.type === 'decrement') {
return { count: state.count - 1 };
}
return state;
}
Syntax
const [state, dispatch] = useReducer(reducer, initialArg, init?)
reducer: The function that specifies how the state gets updated. It must be pure, take the state and action as arguments, and return the next state.initialArg: The value from which the initial state is calculated.dispatch: The function returned byuseReducerthat lets you trigger a state update by passing it an action object.
Example Usage
import { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'increment_age': {
return {
name: state.name,
age: state.age + 1
};
}
case 'changed_name': {
return {
name: action.payload, // Data passed along with the action
age: state.age
};
}
default:
throw new Error('Unknown action: ' + action.type);
}
}
export default function Form() {
const [state, dispatch] = useReducer(reducer, { name: 'Taylor', age: 42 });
return (
<>
<input
value={state.name}
onChange={e => dispatch({ type: 'changed_name', payload: e.target.value })}
/>
<button onClick={() => dispatch({ type: 'increment_age' })}>
Increment age
</button>
<p>Hello, {state.name}. You are {state.age}.</p>
</>
);
}
useState vs useReducer
- Code size:
useStaterequires less setup code.useReducerrequires writing both a reducer function and dispatch actions. - Readability:
useStateis easier to read for simple state (like booleans or strings). When state updates become complex and intertwined,useReducercan clearly separate the what happened (actions) from how the state updates (reducer). - Testing: A reducer is a pure function that doesn’t depend on your component. This means you can export it and test it in isolation independently.
Interview Questions
Q: When would you choose to use useReducer over useState?
A: You should use useReducer when you have complex state logic that involves multiple sub-values or nested objects, or when the next state depends heavily on the previous state. It centralizes all state mutations into a single predictable reducer function, much like Redux.