React Interview Question: Controlled vs Uncontrolled Components

A
Author
31 Jul, 2026 1 min read 1.18K views

Short answer: a controlled input's value comes from React state and changes through onChange. An uncontrolled input keeps its own value in the DOM; you read it when needed (via a ref or FormData).

Controlled

function Search() {
  const [query, setQuery] = useState('');
  return (
    <>
      <input value={query} onChange={(e) => setQuery(e.target.value)} />
      <p>{query.length}/50 characters</p>
    </>
  );
}
  • React state is the single source of truth.
  • Easy to validate as the user types, transform input, or enable/disable buttons.
  • Re-renders on every keystroke (usually fine).

Uncontrolled

function Signup() {
  async function submit(formData) {
    await api.signup(Object.fromEntries(formData));
  }
  return (
    <form action={submit}>
      <input name="email" type="email" defaultValue="" required />
      <button>Sign up</button>
    </form>
  );
}
  • Less code, fewer re-renders.
  • Works naturally with React 19 form actions and progressive enhancement.
  • Harder to react to every change (live validation, dependent fields).

Common bug

<input value={name} />   // no onChange: the field becomes read-only
<input value={user.name ?? undefined} onChange={...} /> // switching between undefined and a value
                                                         // triggers the "uncontrolled to controlled" warning

Use defaultValue for uncontrolled inputs, and make sure controlled inputs always have a defined value (use '' instead of undefined).

How to choose

Simple forms submitted as a whole: uncontrolled with actions or a form library. Inputs that drive other UI as you type: controlled.

Was this article helpful?

Comments

No comments yet. Have a question or a tip? Be the first to share it.

Leave a comment

Comments are reviewed before they appear.