Controlled vs Uncontrolled
Who owns the state? Learn the difference between components that manage themselves versus components managed by their parents.
What do the terms mean?
An **uncontrolled** component keeps its own local state. It decides what to do when interacted with. You just render it and let it do its thing.
A **controlled** component has no local state. Its parent passes down the current state via a prop (like value or isOpen), and a callback function (like onChange or onToggle). The parent is in complete control.
Why does it matter?
Uncontrolled components are very easy to use (less boilerplate). If you just need a standard Accordion that opens and closes when clicked, uncontrolled is perfect.
But what if you want a button *outside* the Accordion to open it? Or what if you want to ensure only one Accordion panel is open at a time? You can't do that if the Accordion manages its own state in secret. You have to 'control' it from the parent.
Native HTML Forms
The most common place you see this is with HTML <input> tags.
**Uncontrolled Input:** <input type='text' /> (The browser's DOM manages the text).
**Controlled Input:** <input type='text' value={text} onChange={e => setText(e.target.value)} /> (React manages the text). If you omit the onChange, the input becomes completely read-only because React forces the value to stay the same!
The Accordion Test
Interact with both accordions. The Uncontrolled accordion handles its own clicks independently. The Controlled accordion is wired to the external buttons at the top.
My state lives in the parent. The buttons outside can control me!
I manage my own state. You can only open me by clicking me directly.
Use the external buttons to toggle the controlled accordion. Notice how the uncontrolled one completely ignores them, because it hides its state from the rest of the app.
Check yourself
Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.
Remember this
- Uncontrolled = manages its own local state.
- Controlled = parent passes state down via props.
- Native HTML inputs can be controlled or uncontrolled.
- If a component needs to coordinate with other components, it must be controlled.
Done with this concept?
Mark it complete to track your progress. No login needed.