Controlled vs Uncontrolled Inputs in React
Jun 6, 2026 · 7 min read
React forms confuse a lot of people, and it usually comes down to one distinction: is the input controlled or uncontrolled? Once that clicks, forms get simple.
Controlled inputs
A controlled input's value comes from React state. You set value and update state in onChange. React is the single source of truth:
function NameField() {
const [name, setName] = useState('');
return (
<input
value={name}
onChange={e => setName(e.target.value)}
/>
);
}Because the value lives in state, you can validate as the user types, format input, disable a submit button, or reset the field — all with normal React code.
Uncontrolled inputs
An uncontrolled input keeps its own value in the DOM, like a plain HTML form. You read it when you need it, usually with a ref:
function NameField() {
const inputRef = useRef(null);
function handleSubmit() {
console.log(inputRef.current.value);
}
return <input ref={inputRef} defaultValue="" />;
}Note defaultValue instead of value — it sets the initial value without taking control of it.
Which should you use?
- Controlled — the default choice. Use it when you need live validation, conditional UI, or to transform the value as it changes.
- Uncontrolled — fine for simple forms where you only read values on submit, or when integrating non-React widgets. It's also handy for file inputs, which are always uncontrolled.
Key takeaways
- Controlled = value in React state (
value+onChange). - Uncontrolled = value in the DOM (
defaultValue+ a ref). - Reach for controlled inputs by default; uncontrolled for simple or non-React cases.
Want the structured path? Explore the React roadmap or browse more articles.