Detailed explanation
In React forms, controlled and uncontrolled describe who owns an input’s current value. A controlled input receives its value from React state, making that state the source of truth. For example, with const [name, setName] = useState(''), you render <input value={name} onChange={e => setName(e.target.value)} />. This matters when the interface must react immediately to user input, such as showing validation messages, enabling a submit button, or synchronising multiple fields. The distinction concerns state ownership, not whether a component is a function or a class.
For a controlled input, typing changes the browser’s input and triggers React’s onChange handler. The handler reads e.target.value and schedules a state update; React then renders with the new state and keeps the DOM value aligned with the value prop. If you pass value without an updating handler, the field effectively becomes read-only unless you deliberately handle updates another way. For checkboxes and radio buttons, control the selection using checked and read e.target.checked. Controlled inputs make dependent fields and programmatic resets straightforward, but state updates can cause unnecessary rendering if form state is placed too high in the tree.
An uncontrolled input keeps its current value in the DOM rather than mirroring every edit into React state. Create a ref with useRef(null), render <input ref={inputRef} defaultValue="Anu" />, and read inputRef.current.value when needed, commonly during submission. defaultValue supplies the initial value; changing it later does not control the current displayed value. Use defaultChecked for initially selected uncontrolled checkboxes. You can also collect uncontrolled fields through FormData using their name attributes, so a separate ref for every field is unnecessary.
Choose controlled inputs when application behaviour depends continuously on field values, and uncontrolled inputs when submission-time access is sufficient or integration with non-React code is simpler. File inputs are uncontrolled because scripts cannot set an arbitrary file selection; read their files property instead. Interviewers usually look for clear ownership, correct value versus defaultValue usage, and awareness that an input should not switch between controlled and uncontrolled during its lifetime. Neither approach automatically guarantees validation or better performance; both require appropriate implementation.
Key points to remember
- Controlled inputs use React state through value and onChange; uncontrolled inputs retain their current value in the DOM.
- Read uncontrolled values through refs or collect named fields with FormData on submission.
- Use checked for controlled checkbox selection and defaultChecked for uncontrolled initial selection.
- defaultValue sets an initial value; it does not continuously control the displayed value.
- Choose based on interaction requirements, and keep each input consistently controlled or uncontrolled.
Common mistakes candidates make
- Passing value without an onChange handler that updates its backing state, unintentionally preventing editing.
- Initialising a controlled text field with undefined or null and later supplying a string, switching its control mode.
- Expecting changes to defaultValue to update the current displayed value of an uncontrolled input.
Likely follow-up questions
Are uncontrolled inputs always faster?
They avoid React state updates for each keystroke when edits are not mirrored into state, which can reduce rendering work. Actual performance depends on the form structure; controlled forms can remain responsive by keeping state local and avoiding expensive renders.
Can uncontrolled inputs support validation?
Yes, they support native constraints such as required and pattern, and you can validate their values during submission. Controlled inputs are often more convenient when validation feedback or related UI must update continuously.
How do you reset controlled and uncontrolled fields?
Reset controlled fields by setting their React state back to the intended initial values. For uncontrolled fields, a native form reset restores their default values; resetting only the DOM is insufficient when React state owns the values.
Interview tip: Explain state ownership first, show one example of each approach, and finish with a practical use case and the controlled-to-uncontrolled warning.
