What is the difference between controlled and uncontrolled form inputs in React? Show both, and say when you would choose each.
Show the explanation
Model answer.
Controlled: React state is the single source of truth. The input's value comes from state and every change goes through onChange.
function EmailForm() {
const [email, setEmail] = useState('');
const invalid = email !== '' && !email.includes('@');
return (
<>
<input value={email} onChange={e => setEmail(e.target.value)} aria-invalid={invalid} />
{invalid && <p role="alert">Enter a valid email</p>}
</>
);
}Uncontrolled: the DOM keeps the value. You read it when needed, through a ref or the form's data on submit.
function QuickSearch() {
function onSubmit(e) {
e.preventDefault();
const q = new FormData(e.currentTarget).get('q');
search(q);
}
return <form onSubmit={onSubmit}><input name="q" defaultValue="" /><button>Go</button></form>;
}Choose controlled when you need instant validation, formatting as the user types, conditionally enabling buttons, or values that depend on each other. Choose uncontrolled for simple forms, file inputs (always uncontrolled), or integrating non-React code; it means fewer re-renders. Libraries like React Hook Form are mostly uncontrolled internally for performance.
A common bug: passing value without onChange makes a read-only input; switching value between undefined and a string triggers the "changing an uncontrolled input to be controlled" warning.
Original UniCircle question. Last reviewed 22 Oct 2026.
