React: From Components to Production · Forms and Validation

Controlled and Uncontrolled Inputs

Choose between React-managed and DOM-managed form values.

A controlled input gets its value from state and updates via onChange, so React always knows the value (instant validation, formatting, conditional fields). An uncontrolled input keeps its value in the DOM; you read it on submit via FormData or refs, which means fewer re-renders and simpler code for basic forms. Both are valid; React 19's form Actions work naturally with uncontrolled inputs.

// Controlled
const [email, setEmail] = useState("");
<input type="email" value={email} onChange={(e) => setEmail(e.target.value.trim())} />

// Uncontrolled with FormData
function SignupForm() {
  function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const data = new FormData(e.currentTarget);
    signup({ email: String(data.get("email")), plan: String(data.get("plan")) });
  }
  return (
    <form onSubmit={handleSubmit}>
      <input name="email" type="email" required defaultValue="" />
      <select name="plan" defaultValue="free"><option value="free">Free</option><option value="pro">Pro</option></select>
      <button>Sign up</button>
    </form>
  );
}

Common pitfalls

  • Switching between controlled and uncontrolled (value={undefined} then a string) — React warns.
  • Setting value without onChange, making the field read-only.
  • Re-rendering huge forms on every keystroke unnecessarily.

Key points

  • Controlled: value in state
  • Uncontrolled: read FormData on submit
  • Don't switch modes for one input

Further reading: react.dev: <input>

Practice questions

Why does React warn about a component changing an uncontrolled input to be controlled?

Answer

The value prop went from undefined (uncontrolled) to a defined value. Initialize state with an empty string instead of undefined.

When are uncontrolled inputs a good choice?

Answer

For simple forms where you only need values on submit, especially with native validation and FormData or React 19 form Actions.

Open in the app to mark lessons complete, take notes and track your progress.