Conceptly
← All Concepts
⌨️

Controlled Components

InteractionThe pattern where React state is the single source of truth for form inputs

Controlled components are the React pattern where form elements such as input, textarea, and select derive their current value from React state. User input updates that state, and the new state is rendered back into the form field.

Architecture Diagram

📊 Data Flow

Dashed line animations indicate the flow direction of data or requests

Why do you need it?

Browsers already keep their own internal form state. If React does not know the current input value, validation, conditional UI, and synchronization with the rest of the app become harder. Once the DOM and React disagree about the real current value, debugging form behavior gets messy.

Why did this approach emerge?

Traditional form handling often waited until submit time and then read values from the DOM all at once. Modern frontend apps needed live validation, instant filtering, and relationships across fields while typing. That pressure made state-driven input control a widely used pattern.

How does it work inside?

A user types, the onChange handler reads the new value, and state updates. On the next render, that state is passed back into the field through value or checked. Because the field always reflects state, the form stays aligned with the rest of the component logic.

In Code

Binding field value and button state to the same source of truth

import { useState } from "react";

export function InviteForm() {
  const [email, setEmail] = useState("");

  return (
    <>
      <input
        value={email}
        onChange={(event) => setEmail(event.target.value)}
        placeholder="name@example.com"
      />
      <button disabled={email.trim() === ""}>Send invite</button>
    </>
  );
}

Because the input and the button logic both read the same state value, React owns the current form state in one place.

Checkboxes also read checked from state

import { useState } from "react";

export function TermsField() {
  const [agreed, setAgreed] = useState(false);

  return (
    <>
      <label>
        <input
          type="checkbox"
          checked={agreed}
          onChange={(event) => setAgreed(event.target.checked)}
        />
        I agree to the terms
      </label>
      <button disabled={!agreed}>Continue</button>
    </>
  );
}

The pattern is the same for checkboxes: the browser does not stay the source of truth. React state does.

When should you use it?

In practice, controlled inputs are especially strong for validation, debounced search, masked input, and UI that enables or disables actions from current field values. But very large forms can still suffer if all state is pushed too high, so field boundaries and ownership matter.

Managing search bars, login forms, and settings panelsShowing validation and error states immediatelyEnabling and disabling buttons based on current form stateSynchronizing input values with other UI or logic