useReducer is an alternative to useState designed for managing complex component state logic, multi-step forms, or state that depends on previous state values.
Inspired by Redux, useReducer separates state transition logic into a pure reducer function: (state, action) => newState.
flowchart LR
Component["UI Event Click"] --> Dispatch["dispatch({ type: 'ADD_ITEM', payload: item })"]
Dispatch --> Reducer["reducer(currentState, action)"]
Reducer --> NewState["Return New Immutable State"]
NewState --> ReRender["Re-render Component UI"]
import React, { useReducer } from 'react';
// Initial Reducer State
const initialState = {
cart: [],
total: 0,
};
// Pure Reducer Function
function cartReducer(state, action) {
switch (action.type) {
case 'ADD_ITEM': {
const updatedCart = [...state.cart, action.payload];
return {
...state,
cart: updatedCart,
total: updatedCart.reduce((sum, item) => sum + item.price, 0),
};
}
case 'REMOVE_ITEM': {
const updatedCart = state.cart.filter((item) => item.id !== action.payload);
return {
...state,
cart: updatedCart,
total: updatedCart.reduce((sum, item) => sum + item.price, 0),
};
}
case 'CLEAR_CART':
return initialState;
default:
throw new Error(`Unhandled action type: ${action.type}`);
}
}
export default function ShoppingCart() {
const [state, dispatch] = useReducer(cartReducer, initialState);
const addItem = () => {
const newItem = { id: Date.now(), name: 'React Book', price: 29.99 };
dispatch({ type: 'ADD_ITEM', payload: newItem });
};
return (
<div className="cart-card">
<h2>Shopping Cart ({state.cart.length} items)</h2>
<p>Total: ${state.total.toFixed(2)}</p>
<button onClick={addItem}>Add React Book ($29.99)</button>
<button onClick={() => dispatch({ type: 'CLEAR_CART' })}>Clear Cart</button>
<ul>
{state.cart.map((item) => (
<li key={item.id}>
{item.name} - ${item.price}
<button onClick={() => dispatch({ type: 'REMOVE_ITEM', payload: item.id })}>
Remove
</button>
</li>
))}
</ul>
</div>
);
}
Math.random()), or mutate state arguments directly. Reducers must purely calculate and return the next state object.{ type: 'ACTION_NAME', payload: data }.Write a reducer function to manage a counter state supporting 'INCREMENT', 'DECREMENT', and 'RESET' action types.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With