Form State Management

How to handle form inputs in React using controlled components, where React state acts as the single source of truth.

React6 min readConcept 38 of 46

The 'Controlled Component' Pattern

In standard HTML, form elements like <input>, <textarea>, and <select> maintain their own internal state based on user input.

In React, we typically prefer to keep all changing data in React's state. When we bind an input's value to a state variable and update that variable on onChange, we create a **Controlled Component**.

In a controlled component, the React state is the "single source of truth". The input only displays what the state tells it to display.

Why control inputs?

Controlling inputs gives you absolute power over the data.

Because you have the exact string the user typed in a state variable on every keystroke, you can easily:

1. Force input formatting (e.g., uppercase only, or phone number masking).

2. Disable the submit button if the input is invalid.

3. Show real-time validation errors as the user types.

4. Pass the current input value to other components (like a live preview).

Handling Multiple Inputs

If you have a form with one input, a single const [email, setEmail] = useState('') is fine. But for forms with many fields, this gets tedious.

Instead, you can use a single state object to hold all form fields:

const [formData, setFormData] = useState({ email: '', password: '' });

Then, use a single onChange handler that reads the name attribute from the input to update the correct property dynamically:

setFormData({ ...formData, [e.target.name]: e.target.value });

The Source of Truth

Type into the login form below. Notice how the React State object (the single source of truth) updates instantly on every keystroke, driving the UI.

// React State (Single Source of Truth)
const formData = {
email: "",
password: ""
};

Welcome Back

Sign in to your account

Network / Console
Waiting for submission...

Notice how every keystroke instantly updates the React State object on the left. The state is what drives the UI, not the other way around.

Check yourself

Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.

  1. 1What makes an `<input>` component 'controlled' in React?
  2. 2If you use an object for form state like `const [form, setForm] = useState({ age: 0, name: '' })`, how do you safely update just the `name`?
  3. 3What is the first thing you should do in a form's `onSubmit` handler?

Remember this

  • Controlled components use React state as the single source of truth.
  • Bind the value prop to state, and update it in onChange.
  • For complex forms, use an object in state and the input's name attribute to update dynamically.
  • Always call e.preventDefault() on form submission to prevent page reloads.
  • Be aware that typing in a controlled input triggers a re-render on every keystroke.

Done with this concept?

Mark it complete to track your progress. No login needed.