Part 10: Controlled vs Uncontrolled Form Components

Part 10 Technology Updated September 12, 2026

Part 10: Controlled vs Uncontrolled Form Components

Handling form inputs (text boxes, checkboxes, select dropdowns) in React can be done via two distinct architectures: Controlled Components and Uncontrolled Components.


1. Controlled Components (The React Standard)

In a controlled component, the input's value is driven by React state (value={state}) and updated via an onChange handler. React is the "single source of truth".

import { useState } from 'react';

export default function ControlledInput() {
  const [email, setEmail] = useState('');

  return (
    <div className="form-group">
      <label htmlFor="email">Email Address:</label>
      <input
        id="email"
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="you@domain.com"
      />
      <p>Current input value: {email}</p>
    </div>
  );
}

Benefits of Controlled Components:

  • Instant validation: Validate input on every keystroke.
  • Dynamic formatting: Automatically uppercase, format phone numbers, or credit card numbers as the user types.
  • Conditional disabling: Disable submit buttons dynamically based on input state.

2. Uncontrolled Components (DOM-Driven)

In an uncontrolled component, the form data is handled directly by the browser DOM itself. You access input values using a useRef hook when the form is submitted.

import { useRef } from 'react';

export default function UncontrolledForm() {
  const nameInputRef = useRef(null);
  const fileInputRef = useRef(null);

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Submitted Name:', nameInputRef.current.value);
    console.log('Selected Files:', fileInputRef.current.files);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" ref={nameInputRef} defaultValue="Guest" />
      {/* File inputs MUST be uncontrolled because their value is read-only in DOM */}
      <input type="file" ref={fileInputRef} />
      <button type="submit">Submit</button>
    </form>
  );
}

3. Which One Should You Choose?

Scenario Controlled Uncontrolled
Instant field validation ❌
Dynamic UI updates based on input ❌
File upload inputs (<input type="file" />) ❌
Simple submit-and-forget forms

Key Takeaways

  • Controlled components keep React state as the single source of truth using value and onChange.
  • Uncontrolled components read values directly from DOM nodes using useRef.
  • File inputs in React must always be uncontrolled.

In Part 11, we will build Multi-Field Forms and Real-World Validation Patterns!