Back to React
React
medium
mid

What is the difference between controlled and uncontrolled components, with examples?

A controlled component's value lives in React state and is driven by props (value + onChange) — React is the single source of truth. An uncontrolled component keeps its own state in the DOM, read via a ref when needed (defaultValue). Controlled = predictable; uncontrolled = less code, fewer re-renders.

5 min read·~8 min to think through

The distinction is about who owns the input's value — React state, or the DOM.

Controlled component

React state is the single source of truth. The input's value is a prop; every change goes through onChangesetState → re-render.

jsx
function ControlledInput() {
  const [name, setName] = useState("");
  return (
    <input value={name} onChange={(e) => setName(e.target.value)} />
  );
}
  • The DOM input can't hold a value React doesn't know about.
  • You can transform/validate/format on every keystroke, disable the submit button reactively, sync with other state.

Uncontrolled component

The DOM keeps its own state. React doesn't track each keystroke; you read the value when you need it (usually on submit) via a ref. Initial value via defaultValue (not value).

jsx
function UncontrolledInput() {
  const inputRef = useRef(null);
  const handleSubmit = () => console.log(inputRef.current.value);
  return <input defaultValue="" ref={inputRef} />;
}

Comparison

ControlledUncontrolled
Source of truthReact stateDOM
Value accessalways available in stateread via ref on demand
Re-renderson every keystrokenone from typing
Instant validation/formattingeasyhard
Codemoreless
File inputsmust be uncontrolled

When to use which

  • Controlled — you need the value during editing: live validation, formatting (currency, phone), conditional UI, dependent fields, controlled clearing.
  • Uncontrolled — simple forms where you only need the value on submit; <input type="file"> (always uncontrolled); integrating with non-React code; performance-sensitive large forms.

The performance angle

A controlled useState per field re-renders on every keystroke. For large forms this matters — which is exactly why React Hook Form uses uncontrolled inputs under the hood (refs) to avoid those re-renders while still giving you validation. So in practice: controlled for small/interactive forms, RHF (uncontrolled) for big ones.

Gotcha

Passing value without onChange makes a read-only input and warns. Switching a component between controlled and uncontrolled (value going undefined → defined) also warns — pick one and keep value always defined.

Follow-up questions

  • Why does React Hook Form use uncontrolled inputs?
  • Why must file inputs be uncontrolled?
  • What warning do you get switching between controlled and uncontrolled, and why?
  • How would you do live input formatting (e.g. currency)?

Common mistakes

  • Passing value without onChange and getting a read-only input.
  • Letting value go from undefined to defined, flipping controlled/uncontrolled.
  • Using controlled state per field on huge forms and causing re-render lag.
  • Trying to control a file input.

Performance considerations

  • Controlled inputs re-render the component on every keystroke; on large forms this is noticeable. Uncontrolled inputs (refs) avoid that — the basis of React Hook Form's performance. Choose based on whether you need the value mid-edit.

Edge cases

  • File inputs — always uncontrolled.
  • Programmatically clearing or setting a value.
  • Integrating with a non-React widget that owns its own DOM state.
  • Initial value arriving asynchronously.

Real-world examples

  • Controlled: a search box filtering results live, a currency input formatting as you type.
  • Uncontrolled: a simple contact form read on submit; React Hook Form's ref-based fields.

Senior engineer discussion

Seniors frame it as ownership of the value and connect it to performance — controlled means a re-render per keystroke, which is why RHF goes uncontrolled. They know the controlled/uncontrolled-switch warning, that file inputs are always uncontrolled, and pick per situation rather than dogmatically.

Related questions