How do you reset a component's state?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
The cleanest way is to change the component's key. React treats a different key as a different component, unmounts the old one, and mounts a fresh instance with fresh state — no reset logic to write or keep in sync.
<ProfileForm key={userId} user={user} />
// userId changes -> the form is recreated, every field back to its initial value
This is the approach the React docs recommend, and it scales: it resets all state in that subtree, including state in children and any refs, without you enumerating it.
The other options, and when they are right
Reset explicitly in a handler when only part of the state should go back:
const initial = { name: '', email: '' };
const [form, setForm] = useState(initial);
const reset = () => setForm(initial); // keeps a sibling "submitted" flag
With useReducer, dispatch a reset action — the initial value stays in the reducer where the rest of the transitions live.
An uncontrolled form resets for free:
<form onSubmit={onSubmit} ref={ref}>...</form>
ref.current.reset(); // the DOM does it
Adjust state during render, the escape hatch for "reset when a prop changes" without a key:
const [prevId, setPrevId] = useState(userId);
if (userId !== prevId) { // runs during render, guarded
setPrevId(userId);
setForm(initial);
}
React re-runs the component immediately without committing the first result, so there is no extra paint. It is more code than a key, which is why the key is the default recommendation.
What not to do
useEffect(() => { setForm(initial); }, [userId]); // avoid
The component renders once with the previous user's data, commits, paints, then the effect fires and it renders again. The user can see the flash, and in a form they can type into stale fields first.
The key gotchas
Using an array index as a key defeats this entirely — reorder or delete an item and React matches the wrong instances, so state sticks to the wrong row. Use a stable id.
And a key forces a real unmount, so anything expensive inside is recreated and any scroll position, focus, or animation state is lost. When the subtree is heavy and you only need one field cleared, reset that field instead.
