Resetting State with Key
Reset component state by changing key: when remount is cleaner than effects that sync props into useState.
- react
- resetting-state
You open user A’s profile form, type half a bio, switch to user B — and still see A’s draft. Local state survived because React reused the same component instance at the same tree position. Changing key tells React this is a different instance: unmount the old one, mount a new one, run initial state again.
Docs: Preserving and Resetting State.
The pattern
function Page({ userId }) {
return (
<section>
<h1>Edit user</h1>
<UserForm key={userId} userId={userId} />
</section>
);
}
function UserForm({ userId }) {
const [bio, setBio] = useState('');
// fresh bio whenever userId-driven remount happens
return (
<textarea
value={bio}
onChange={(e) => setBio(e.target.value)}
aria-label="Bio"
/>
);
}
Parent owns which entity is selected. Child owns draft UI state. Key bridges them without useEffect(() => setBio(''), [userId]).
Why not an effect?
// Works until it races with typing, network revalidation, or partial updates
useEffect(() => {
setBio(serverBio);
}, [userId, serverBio]);
Effects that copy props into state are a top footgun (derived state). Remounting is explicit: old draft is gone, subscriptions restart, refs reset.
When remount is wrong
| Goal | Prefer |
|---|---|
| Keep draft while parent re-renders | Stable key; do not key on unrelated props |
| Soft reset one field | setField(initial) in an event handler |
| Animate between states | Avoid full remount; keep instance |
| Expensive mount (charts, editors) | Explicit reset API via ref / imperative handle |
// Only reset when the document identity changes — not when theme toggles
<Editor key={doc.id} doc={doc} theme={theme} />
Putting theme in the key would destroy editor undo stacks on every palette change.
Lists and forms together
Multi-step wizards often key each step’s panel so leaving a step drops ephemeral UI, while lifted form state in the parent survives:
function Wizard({ step, data, onChange }) {
return (
<>
<StepPanel key={step} step={step} data={data} onChange={onChange} />
<nav>{/* next / back */}</nav>
</>
);
}
Lift durable answers; key the step chrome. See multi-step forms.
Combined with error recovery
Error boundaries often remount children by bumping a resetKey after “Try again,” clearing the crashed fiber’s poisoned state.
const [resetKey, setResetKey] = useState(0);
return (
<ErrorBoundary onReset={() => setResetKey((k) => k + 1)} key={resetKey}>
<Chart />
</ErrorBoundary>
);
Interview out-loud
“I reset state by changing the component’s key when the entity identity changes, which remounts the subtree with fresh useState. That is cleaner than effects that mirror props into state. I keep keys tied to identity, not to every prop that happens to change.”
Related on this site
Further reading
Production checklist
Before you ship a change in this area, walk the list out loud:
- What is the source of truth for the data on screen?
- What happens on remount, route change, and Strict Mode double-invoke?
- Which updates are urgent (input) versus deferrable (filter large lists)?
- Did you profile before adding memo, context splits, or virtualization?
- Is there an accessibility path: keyboard, focus, names, and errors?
If you cannot answer those, the API knowledge will not save the interview or the incident.
Related guides
- Accessibility Patterns in ReactPractical React a11y: labels, focus management, keyboard, live regions, and composition patterns that stay accessible.
- Avoid Prop Drilling with CompositionStop threading props through intermediates: children slots, inversion of control, and when context is the right escape hatch.
- Batching State UpdatesHow React 18+ batches setState in events, timeouts, and promises: when updates flush and why double setState still works.
- Children Prop PatternsUsing children and slot props for flexible APIs: wrappers, compound components, and when to prefer explicit props.
- Client Component BoundariesWhere to put use client: push interactivity to leaves, serializable props, and children as server slots.