Reset and initialize both touch useReducer state. Initialization sets the starting value once, and a reset action restores that value after the user has changed it.
Getting both right keeps a form or cart easy to return to its original shape without recreating the logic by hand. The two mechanisms are separate: one runs at mount, and the other runs when you choose.
Initialize with the third argument
The third argument to useReducer is an initializer function. React calls it once with the second argument and stores its return value as the initial state. This keeps expensive setup out of every render, which matters when the starting value comes from a prop or a large list.
function createInitialState(username) {
return { name: username, cart: [] };
}
function Cart({ username }) {
const [state, dispatch] = useReducer(reducer, username, createInitialState);
return <p>Shopping as {state.name}</p>;
}createInitialState receives the username and builds the starting object only during the first render. The component re-runs on later renders, but the initializer does not. If the initializer needs no input, pass null as the second argument.
Passing the function itself, not a call to it, is what keeps initialization lazy. Writing createInitialState(username) instead runs the function on every render.
Reset with an action
A reset action is just a reducer case that returns the initial state object again. Keep that object in a constant so the first render and the reset action reference the same shape.
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case "incremented": return { ...state, count: state.count + 1 };
case "reset": return initialState;
default: return state;
}
}Dispatching reset replaces the current state with initialState, so the next render shows the starting values. Unlike the initializer, this runs in response to a user action rather than on mount, which makes it reusable. An action-based reset also shows up in reducer logs, so you can see when the user returned to the start.
Reset everything with a component key
When a reset should also clear local state that lives outside the reducer, change the key on the component. React unmounts the old instance and mounts a fresh one, which re-runs every initializer.
function App() {
const [version, setVersion] = useState(0);
return (
<>
<button onClick={() => setVersion(version + 1)}>Reset</button>
<Form key={version} />
</>
);
}Clicking Reset bumps version, which changes the key and remounts Form. Every hook inside Form, including useReducer, starts over.
This is the bluntest tool because it throws away local state, refs, and effects together. See preserve and reset state with component keys for the details.
When each approach fits
Use the initializer for first-render setup, a reset action to restore one reducer's shape, and a key when you must clear state across several hooks at once. Prefer the reset action when you can, because it keeps the reset visible in reducer logs. Naming the reset action after the event keeps the intent clear; how to write actions and reducers covers the naming rules.
Rune AI
Key Insights
- The third argument is an initializer function.
- Pass null as the second argument when the initializer needs no data.
- A reset action returns the initial state object.
- Changing a key remounts a component and resets all state.
- Never rebuild expensive initial state on every render.
Frequently Asked Questions
What is the third argument to useReducer?
How do I reset useReducer state?
Does the initializer run on every render?
Conclusion
Initialize useReducer state with an initializer function passed as the third argument, and reset it by dispatching an action that returns the initial state. Use a component key when you want to reset every piece of state at once.
More in this topic
How to Build a Dropdown Menu in React
Build a React dropdown menu with the ARIA menu button pattern. Handle open and close, keyboard arrows, and clicks outside the menu.
How to Animate React Components with Motion
Animate React components with the Motion library. Set up motion, add enter, hover, and exit animations, and respect reduced motion.
Headless UI Components Explained: Logic Without Locked Styling
Understand headless UI components and how libraries like Radix give you unstyled, accessible behavior that you style yourself.