All visualizationsReact · 3 of 18
Controlled inputs — one memory, or a form that lies
Run the drift: the box says "hi", your state says "" — then wire the keystrokes through state and watch them agree forever.
💡
THE BIG IDEA
Every input box has its own private memory — it worked that way for decades before React. Leave it alone and your state quietly drifts from what the screen shows, which is exactly the bug behind "the form submitted empty". Controlled inputs install a wire: every keystroke routes through state, the box repaints from state, and the two can never disagree. We run the drift, the fix, and the two-way superpower.
Move your mouse over any line to see what it does. Hover a loop line and it plays through every repeat. Or press ▶ Play to watch the whole thing. On a phone, tap the arrows.
1const dom = { value: "" };
2let state = "";
3function typeUncontrolled(ch) { dom.value += ch; }
4function typeControlled(ch) {
5 state += ch;
6 dom.value = state;
7}
8typeUncontrolled("h"); typeUncontrolled("i");
9console.log("uncontrolled → box:", dom.value, "| state:", JSON.stringify(state));
10state = ""; dom.value = "";
11typeControlled("o"); typeControlled("k");
12console.log("controlled → box:", dom.value, "| state:", JSON.stringify(state));
13state = state.toUpperCase();
14dom.value = state;
15console.log("state changed → box follows:", dom.value);
A user types "hi" into your form, presses Save — and your code saves an EMPTY string. The box clearly says hi. Your state says nothing. Who is lying?
Nobody: there are simply TWO memories — the input box’s own (the DOM value) and yours (state) — and no wire between them. This lesson runs the drift, then installs the wire.
📦 Memory boxes
what the program is remembering right now
nothing remembered yet
🖥️ What the computer shows
the answers the program prints out
nothing yet
1/10
UP NEXT IN REACT
Custom hooks — a recipe, never a shared pot
Build useToggle on the mini-useState shelf, call it twice, flip one — and prove the other never moves.
Prop drilling vs Context — couriers vs the broadcast towerCustom hooks — a recipe, never a shared pot