Part 10: Controlled vs Uncontrolled Form Components
Handling form inputs (text boxes, checkboxes, select dropdowns) in React can be done via two distinct architectures: Controlled Components and Uncontrolled Components.
1. Controlled Components (The React Standard)
In a controlled component, the input's value is driven by React state (value={state}) and updated via an onChange handler. React is the "single source of truth".
import { useState } from 'react';
export default function ControlledInput() {
const [email, setEmail] = useState('');
return (
<div className="form-group">
<label htmlFor="email">Email Address:</label>
<input
id="email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="you@domain.com"
/>
<p>Current input value: {email}</p>
</div>
);
}
Benefits of Controlled Components:
- Instant validation: Validate input on every keystroke.
- Dynamic formatting: Automatically uppercase, format phone numbers, or credit card numbers as the user types.
- Conditional disabling: Disable submit buttons dynamically based on input state.
2. Uncontrolled Components (DOM-Driven)
In an uncontrolled component, the form data is handled directly by the browser DOM itself. You access input values using a useRef hook when the form is submitted.
import { useRef } from 'react';
export default function UncontrolledForm() {
const nameInputRef = useRef(null);
const fileInputRef = useRef(null);
const handleSubmit = (e) => {
e.preventDefault();
console.log('Submitted Name:', nameInputRef.current.value);
console.log('Selected Files:', fileInputRef.current.files);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={nameInputRef} defaultValue="Guest" />
{/* File inputs MUST be uncontrolled because their value is read-only in DOM */}
<input type="file" ref={fileInputRef} />
<button type="submit">Submit</button>
</form>
);
}
3. Which One Should You Choose?
| Scenario | Controlled | Uncontrolled |
|---|---|---|
| Instant field validation | ❌ | |
| Dynamic UI updates based on input | ❌ | |
File upload inputs (<input type="file" />) |
❌ | |
| Simple submit-and-forget forms |
Key Takeaways
- Controlled components keep React state as the single source of truth using
valueandonChange. - Uncontrolled components read values directly from DOM nodes using
useRef. - File inputs in React must always be uncontrolled.
In Part 11, we will build Multi-Field Forms and Real-World Validation Patterns!

