What is the difference between controlled and uncontrolled components in React?
Controlled components store form input values in React state; uncontrolled components let the DOM manage the value and read it via a ref.
React
Overview
In a **controlled** component, React is the "single source of truth" for the input's value - you store it in state and pass it back to the input via `value`. In an **uncontrolled** component, the DOM manages the value internally and you read it via a `ref` when needed.
Key Points
- •Controlled: `value` + `onChange` both wired to React state. React owns the value.
- •Uncontrolled: no `value` prop. Use a `ref` to read the input's current value on demand.
- •Use `defaultValue` (not `value`) to set an initial value in uncontrolled inputs.
- •Controlled components enable real-time validation, conditional enabling, and instant feedback.
- •Uncontrolled components are simpler and closer to plain HTML, but harder to synchronise.
- •File inputs are always uncontrolled - the browser manages the file list.
Examples
Controlled input (React owns the value)
tsximport { useState } from 'react';
function ControlledForm() {
const [email, setEmail] = useState('');
const isValid = email.includes('@');
return (
<form onSubmit={e => { e.preventDefault(); console.log(email); }}>
<input
type="email"
value={email} // React drives the value
onChange={e => setEmail(e.target.value)} // React updates on every keystroke
style={{ borderColor: isValid ? 'green' : 'red' }} // real-time validation
/>
<button disabled={!isValid}>Submit</button>
</form>
);
}Uncontrolled input (DOM owns the value)
tsximport { useRef } from 'react';
function UncontrolledForm() {
const emailRef = useRef<HTMLInputElement>(null);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
console.log(emailRef.current?.value); // read value on submit only
};
return (
<form onSubmit={handleSubmit}>
<input type="email" defaultValue="" ref={emailRef} />
<button type="submit">Submit</button>
</form>
);
}When to choose each
textControlled | Uncontrolled
-------------------|------------------
Real-time validation| Simple read-on-submit
Dependent fields | One-time forms
Format as you type | File inputs
Derived UI state | Quick prototypesPro Tip
Libraries like React Hook Form and Formik work primarily with uncontrolled inputs (using refs) for performance - they avoid re-rendering the whole form on every keystroke. For most application forms, controlled inputs are the idiomatic React approach.