Controlled vs Uncontrolled Components
Controlled = React manages, Uncontrolled = DOM manages
Controlled Components
"React controls the value"
Controlled components have their value controlled by React state.
"Controlled components have their value controlled by React state, with React as the single source of truth."
Controlled Component Example
value + onChange = controlled
function ControlledInput() {
const [value, setValue] = useState("");
return <input value={value} onChange={(e) => setValue(e.target.value)} />;
}
"Controlled components use value prop and onChange handler, with state managing the input value."
Uncontrolled Components
"DOM manages the value"
Uncontrolled components let the DOM manage the value using refs.
"Uncontrolled components let the DOM manage the value, accessed via refs rather than React state."
Uncontrolled Component Example
ref to access DOM value
function UncontrolledInput() {
const inputRef = useRef(null);
const handleSubmit = () => {
console.log(inputRef.current.value);
};
return (
<>
<input ref={inputRef} />
<button onClick={handleSubmit}>Submit</button>
</>
);
}
"Uncontrolled components use refs to access DOM values, with the DOM as the source of truth."
When to Use Controlled
Need React state · Validation · Real-time updates
Use controlled when:
- Need to validate on every keystroke
- Need to format input
- Need to disable submit based on value
- Need to reset form programmatically
"Use controlled components when you need validation, formatting, or programmatic control over the input value."
When to Use Uncontrolled
Simple forms · File inputs · Performance
Use uncontrolled when:
- Simple forms
- File inputs (must be uncontrolled)
- Performance matters (fewer re-renders)
- Integrating with non-React code
"Use uncontrolled components for simple forms, file inputs, or when performance is critical."
File Inputs
File inputs must be uncontrolled
function FileInput() {
const fileRef = useRef(null);
const handleSubmit = () => {
const file = fileRef.current.files[0];
// Process file
};
return <input type="file" ref={fileRef} onChange={handleSubmit} />;
}
File inputs are read-only and must be uncontrolled.
"File inputs must be uncontrolled because they're read-only and React can't set their value."
Comparison
Controlled = more control, Uncontrolled = simpler
| Aspect | Controlled | Uncontrolled |
|---|---|---|
| Value source | React state | DOM |
| Updates | onChange handler | DOM native |
| Validation | Easy | Manual |
| Performance | More re-renders | Fewer re-renders |
| Complexity | More code | Less code |
"Controlled components offer more control and easier validation, while uncontrolled are simpler with better performance."
9️⃣ Hybrid Approach
Default value + ref
function HybridInput() {
const inputRef = useRef(null);
return (
<input
ref={inputRef}
defaultValue="initial"
onChange={() => {
// Access via ref when needed
console.log(inputRef.current.value);
}}
/>
);
}
Use defaultValue for initial value, ref for access.
"Hybrid approach uses defaultValue for initial value and refs for accessing current value."
Best Practices
✅ Use controlled for most forms ✅ Use uncontrolled for file inputs ✅ Use controlled when validation needed ✅ Use uncontrolled for simple, performance-critical inputs ✅ Prefer controlled for React integration
"Controlled components have values controlled by React state via value and onChange. Uncontrolled components let the DOM manage values, accessed via refs. Controlled offers more control and validation, uncontrolled is simpler with better performance. File inputs must be uncontrolled. Choose based on needs - controlled for validation, uncontrolled for simplicity."
🧠 Ultra-Short Cheat Sheet
Controlled = React state (value + onChange)
Uncontrolled = DOM (ref)
Controlled: validation, control
Uncontrolled: simple, performance
File inputs = uncontrolled
Choose based on needs