What are "controlled" and "uncontrolled" components?
Main idea
In React, input fields (<input>, <textarea>, <select>) can work in two ways:
| Type | Who controls the value |
|---|---|
| Controlled | React (through state) |
| Uncontrolled | The DOM itself (the field's internal value) |
1. Controlled (controlled component)
A controlled component is a form element whose value is fully controlled by React state.
Example
javascript
function Form() {
const [name, setName] = useState("");
return (
<div>
<input
value={name} // the value comes from state
onChange={(e) => setName(e.target.value)} // update the state
/>
<p>You entered: {name}</p>
</div>
);
}Here:
valueis always synchronized withstate- every change goes through
setName - React is the "source of truth"
In other words: DOM → React → render → DOM React knows exactly what is currently in the input.
Pros of controlled components
- Full control over the form's data
- Easy to do real-time validation
- You can react to input (for example, enable a button)
- You can reset / synchronize the value programmatically
Cons
- More code (
value,onChange) - With a very large number of inputs (for example, 500+) it can be inefficient → but in ordinary forms this is not a problem
2. Uncontrolled (uncontrolled component)
An uncontrolled component is a form element whose value is stored inside the DOM, not in React state.
Example
javascript
function Form() {
const inputRef = useRef();
const handleSubmit = () => {
alert("You entered: " + inputRef.current.value);
};
return (
<div>
<input ref={inputRef} defaultValue="Tim" /> {/* defaultValue instead of value */}
<button onClick={handleSubmit}>Submit</button>
</div>
);
}Here:
- React does not know what is currently in the input
- the value is stored in the DOM
- we retrieve it manually through a
ref
Pros of uncontrolled components
- Less code, simpler for small forms
- Good when you do not need to react to every change
- Sometimes convenient when integrating with legacy code or external libraries
Cons
- React does not know the field's current value
- You cannot do instant validation or auto-updates
- You cannot reset the value through
setState- only through the DOM
3. Comparison in practice
| Characteristic | Controlled | Uncontrolled |
|---|---|---|
| Who stores the value | React state | DOM |
| How the initial value is set | value={state} | defaultValue="..." |
| How the value is read | From state | Through ref.current.value |
| When to use | When you need to react to input | When the form is simple and no reaction is needed |
| Usage examples | Registration, search, filters | Quick forms, third-party plugins |
| Can it be reset from React | Yes | No (only manually) |
4. A typical validation example
Controlled (easy)
javascript
function LoginForm() {
const [email, setEmail] = useState("");
const isValid = email.includes("@");
return (
<form>
<input value={email} onChange={e => setEmail(e.target.value)} />
<button disabled={!isValid}>Log in</button>
</form>
);
}Uncontrolled (harder)
javascript
function LoginForm() {
const emailRef = useRef();
const handleSubmit = (e) => {
e.preventDefault();
const email = emailRef.current.value;
if (!email.includes("@")) alert("Invalid email");
};
return (
<form onSubmit={handleSubmit}>
<input ref={emailRef} defaultValue="" />
<button>Log in</button>
</form>
);
}5. When to use which approach
| Situation | What to choose |
|---|---|
| A form with dynamic validation | Controlled |
| A form whose value needs to be reset / synchronized | Controlled |
| A simple form that does not need control | Uncontrolled |
| Integration with third-party JS libraries | Uncontrolled |
| Forms with dozens of inputs and no dynamics | Uncontrolled (for optimization) |
Combined approach
Sometimes a hybrid is used - controlled + uncontrolled.
For example, defaultValue sets the start, and then React starts controlling:
javascript
<input defaultValue="Tim" onChange={(e) => setName(e.target.value)} value={name} />React "enters the game" after the first change - but it is better to either control the field completely, or not control it at all.
Summary
| Component type | Controls the value | Where it is stored | Application |
|---|---|---|---|
| Controlled | React | In state | When you need control, validation, resetting |
| Uncontrolled | DOM | In the element itself | Simple, static forms, integration with legacy code |
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.