React's Controlled vs. Uncontrolled Components

A controlled component is a form input whose value is driven by React state; an uncontrolled component lets the DOM manage its own state. Use controlled for instant validation or conditional logic.
WHY IT EXISTS In HTML, form elements like <input> and <textarea> naturally keep their own state. When you type, the browser updates the DOM node. React introduces a choice: should the component's state live in the DOM, or should it live in your React component's state? This decision defines whether a component is controlled or uncontrolled.
THE MENTAL MODEL Think of a controlled component as a puppet. React state is the puppeteer, pulling the strings. The input's value is explicitly set by a state variable, and any change (like typing) must go through a state update via onChange. An uncontrolled component is more like a free agent; it manages its own state internally in the DOM, and React just asks for the final value when it needs it, typically on form submission using a ref.
HOW IT WORKS A controlled component binds its value prop to a React state variable (e.g., from useState). It also provides an onChange handler that calls the state setter function. This creates a loop: user types -> onChange fires -> state updates -> component re-renders -> input's value prop gets the new state. The React state is the single source of truth. For an uncontrolled component, you typically omit the value prop and use a ref to read the element's value directly from the DOM when you need it, like inside a submit handler.
WHEN TO USE IT Use controlled components when you need to implement instant validation, enforce a specific input format (like for a credit card), conditionally disable a submit button, or have one input's value affect another. They give you fine-grained control over the form data at all times, as the state is always current.
WHEN NOT TO USE IT Uncontrolled components can be simpler for very basic forms where you don't need to react to input in real-time and only care about the value on submission. They can also be a better choice for integrating with non-React code or managing file inputs, which are inherently uncontrolled by nature.
ONE CANONICAL EXAMPLE A search bar with live suggestions is a classic controlled component. The input's value is held in state. On every onChange, you update the state and use that new value to fetch and display search results. If you only cared about the value when the user hit 'Submit', you could use an uncontrolled component and a ref to read the value once.
Read the original → react.dev
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.