← Back to Chapters

Controlled Components in React

⚛️ Controlled Components in React

? Quick Overview

A controlled component in React is a form element whose value is managed by React state. Instead of the browser managing input values, React becomes the single source of truth.

This gives predictable behavior and enables features like validation, formatting, and real-time UI updates.

? Key Concepts

  • State Driven Input values come from React state.
  • onChange Updates state whenever the user types.
  • Two-Way Binding State updates UI and UI updates state.
  • Single Source of Truth No unsynced DOM values.

? Syntax / Theory

  • The value attribute must always reference state.
  • The onChange handler must update state.
  • Initial state defines the default value of the input.
  • Without state binding, inputs become uncontrolled.

? Code Example: Single Input

? View Code Example
// Controlled input using React state
import React, { useState } from "react";

function ControlledInput() {
const [name, setName] = useState("");

const handleChange = (e) => {
setName(e.target.value);
};

return (
<div>
<h4>Controlled Input Example</h4>
<input type="text" value={name} onChange={handleChange} placeholder="Enter your name" />
<p>Hello, {name || "Guest"}!</p>
</div>
);
}

? Code Example: Multiple Fields Form

? View Code Example
// Handling multiple inputs using a single state object
function ControlledForm() {
const [formData, setFormData] = React.useState({
username: "",
email: ""
});

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

const handleSubmit = (e) => {
e.preventDefault();
alert(`User: ${formData.username}\nEmail: ${formData.email}`);
};

return (
<form onSubmit={handleSubmit}>
<input type="text" name="username" value={formData.username} onChange={handleChange} />
<input type="email" name="email" value={formData.email} onChange={handleChange} />
<button type="submit">Submit</button>
</form>
);
}

? Code Example: Select and Textarea

? View Code Example
// Controlled dropdown and textarea
function FeedbackForm() {
const [feedback, setFeedback] = React.useState({
rating: "Good",
comment: ""
});

const handleChange = (e) => {
const { name, value } = e.target;
setFeedback({ ...feedback, [name]: value });
};

return (
<form>
<select name="rating" value={feedback.rating} onChange={handleChange}>
<option>Excellent</option>
<option>Good</option>
<option>Average</option>
<option>Poor</option>
</select>
<textarea name="comment" value={feedback.comment} onChange={handleChange}></textarea>
<p>Your feedback: {feedback.comment || "No comment yet"}</p>
</form>
);
}

? Interactive Example (Simulated Controlled Input)

This interactive demo simulates how a controlled component works by keeping the input value and UI display perfectly synchronized.

Hello Guest (Role: Student)

? Live Output / Explanation

  • Typing updates React state instantly.
  • Displayed value always matches internal state.
  • Select changes update state dynamically.
  • Textarea reflects user input in real time.

This guarantees consistent two-way data flow and eliminates unsynced input issues.

? Tips & Best Practices

  • Always initialize state before rendering forms.
  • Use one state object for large forms.
  • Perform validation inside onChange or onSubmit.
  • Keep inputs lightweight and reusable.

? Try It Yourself

  1. Create a form with username, email, and password.
  2. Add a dropdown and display its value below.
  3. Show validation messages when input is empty.
  4. Refactor into a custom hook like useForm().

Goal: Build confidence managing form inputs using React state.