Definition: A controlled input is an input element whose value is managed by React state.
The value of the input is always determined by the component's state (usually via useState).
The onChange event updates the state, and the state updates the input's value.
Key points:
- React is the single source of truth.
- Makes form behavior predictable.
- Useful when you need validation, formatting, or dynamic updates.
Example:
import { useState } from 'react';
function ControlledInput() {
const [name, setName] = useState('');
return (
<input
type="text"
value={name} // value comes from state
onChange={(e) => setName(e.target.value)} // state updates on change
/>
);
}Definition: An uncontrolled input is an input element whose value is managed by the DOM itself, not React.
You read the value only when you need it, usually via a ref. React does not store the current value in state.
Key points:
- The DOM is the source of truth.
- Less code, but less control.
- Useful for quick forms or when migrating legacy code.
Example:
import { useRef } from 'react';
function UncontrolledInput() {
const inputRef = useRef();
const handleSubmit = () => {
alert(inputRef.current.value); // directly read from DOM
};
return (
<>
<input type="text" ref={inputRef} /> {/* No value in state */}
<button onClick={handleSubmit}>Submit</button>
</>
);
}| Feature | Controlled | Uncontrolled |
|---|---|---|
| State location | React state | DOM |
| Value access | state variable | ref or querySelector |
| Source of truth | React | Browser DOM |
| Performance | May re-render on every keystroke | Fewer re-renders |
| Use cases | Validation, formatting, conditional rendering | Quick forms, minimal interaction |
| Ease of testing | Easier (all state in React) | Slightly harder |
Rule of thumb:
If you need real-time validation, conditional UI changes, or syncing input with other state, use controlled inputs.
If you just need the value once on submit and don’t care about intermediate changes, uncontrolled is simpler.