Controlled Inputs
Controlled Inputs
How Controlled Inputs Work
- Input value is bound to state:
value={state} - onChange updates state:
onChange={(e) => setState(e.target.value)} - State changes trigger re-render
- Input displays new value
Text Input
function TextInput() {
const [value, setValue] = useState("");
return (
<div>
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Type something..."
/>
<p>You typed: {value}</p>
</div>
);
}
Checkbox
function Checkbox() {
const [isChecked, setIsChecked] = useState(false);
return (
<div>
<input
type="checkbox"
checked={isChecked}
onChange={(e) => setIsChecked(e.target.checked)}
/>
<label>I agree to the terms</label>
</div>
);
}
Select
function Select() {
const [selected, setSelected] = useState("");
return (
<select value={selected} onChange={(e) => setSelected(e.target.value)}>
<option value="">Select an option</option>
<option value="apple">Apple</option>
<option value="banana">Banana</option>
<option value="cherry">Cherry</option>
</select>
);
}
Textarea
function Textarea() {
const [text, setText] = useState("");
return (
<div>
<textarea
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="Enter your message..."
/>
<p>Characters: {text.length}</p>
</div>
);
}
Multiple Inputs
Multiple Inputs
Single Handler for Multiple Inputs
function Form() {
const [formData, setFormData] = useState({
firstName: "",
lastName: "",
email: "",
age: ""
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prev) => ({
...prev,
[name]: value
}));
};
return (
<form>
<input
name="firstName"
value={formData.firstName}
onChange={handleChange}
placeholder="First Name"
/>
<input
name="lastName"
value={formData.lastName}
onChange={handleChange}
placeholder="Last Name"
/>
<input
name="email"
type="email"
value={formData.email}
onChange={handleChange}
placeholder="Email"
/>
<input
name="age"
type="number"
value={formData.age}
onChange={handleChange}
placeholder="Age"
/>
</form>
);
}
Nested State
function ProfileForm() {
const [formData, setFormData] = useState({
name: "",
address: {
street: "",
city: "",
state: "",
zip: ""
}
});
const handleChange = (e) => {
const { name, value } = e.target;
const keys = name.split(".");
setFormData((prev) => {
const newData = { ...prev };
let current = newData;
for (let i = 0; i < keys.length - 1; i++) {
current[keys[i]] = { ...current[keys[i]] };
current = current[keys[i]];
}
current[keys[keys.length - 1]] = value;
return newData;
});
};
return (
<form>
<input name="name" value={formData.name} onChange={handleChange} />
<input name="address.street" value={formData.address.street} onChange={handleChange} />
<input name="address.city" value={formData.address.city} onChange={handleChange} />
</form>
);
}
Resetting Forms
function Form() {
const [formData, setFormData] = useState({ name: "", email: "" });
const handleSubmit = (e) => {
e.preventDefault();
// Submit logic
setFormData({ name: "", email: "" }); // Reset
};
}
Validation
Validation
Basic Validation
function Form() {
const [formData, setFormData] = useState({ email: "", password: "" });
const [errors, setErrors] = useState({});
const validate = () => {
const newErrors = {};
if (!formData.email) {
newErrors.email = "Email is required";
} else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {
newErrors.email = "Invalid email format";
}
if (!formData.password) {
newErrors.password = "Password is required";
} else if (formData.password.length < 8) {
newErrors.password = "Password must be at least 8 characters";
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = (e) => {
e.preventDefault();
if (validate()) {
// Submit
}
};
}
Real-time Validation
function Form() {
const [formData, setFormData] = useState({ email: "" });
const [errors, setErrors] = useState({});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prev) => ({ ...prev, [name]: value }));
// Validate on change
if (name === "email") {
if (!value) {
setErrors((prev) => ({ ...prev, email: "Email is required" }));
} else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) {
setErrors((prev) => ({ ...prev, email: "Invalid email" }));
} else {
setErrors((prev) => ({ ...prev, email: null }));
}
}
};
}
Error Display
function Form() {
return (
<form>
<div>
<input name="email" value={formData.email} onChange={handleChange} />
{errors.email && <span className="error">{errors.email}</span>}
</div>
</form>
);
}
Practice Problems
Create a reusable React component implementing Controlled Components. Include proper state management and accessibility.
Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where neededWrite unit and integration tests for Controlled Components using React Testing Library.
Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility testsOptimize Controlled Components for performance. Consider memoization, code splitting, and bundle size.
Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysisQuiz
1. What makes an input 'controlled'?
2. How do you handle multiple inputs with one handler?
3. What is the checked prop used for?
4. When should you validate form data?
Flashcards
Question
What is a controlled component?
Click to reveal answer
Answer
A component where React state controls the form input value
Question
How do you reset a form?
Click to reveal answer
Answer
Set state back to initial values
Question
What prop controls checkbox state?
Click to reveal answer
Answer
The checked prop
Question
How do you display validation errors?
Click to reveal answer
Answer
Check if errors exist and render error messages
Question
What is Controlled Components?
Click to reveal answer
Answer
Controlled Components is a key concept in frontend development.
Revision Notes
Key Takeaways
- 1.Controlled inputs use React state
- 2.One handler can manage multiple inputs
- 3.Use checked for checkboxes
- 4.Validate on change, blur, and submit
- 5.Display errors next to inputs
Interview Tips
- •Show how to create controlled inputs
- •Demonstrate handling multiple inputs
- •Explain validation strategies
Cheat Sheet
Cheat Sheet
Controlled Input
<input value={val} onChange={(e) => setVal(e.target.value)} />
Multiple Inputs
<input name="email" onChange={handleChange} />
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
Checkbox
<input type="checkbox" checked={val} onChange={(e) => setVal(e.target.checked)} />
Validation
const validate = () => {
const errors = {};
if (!email) errors.email = "Required";
setErrors(errors);
return Object.keys(errors).length === 0;
};