Controlled Input
React · Example / how-to
Controlled Input
React · Example / how-to
📋 Overview
Keep an input’s value in React state (controlled component) so validation and submit logic stay in sync with the UI.
🔧 Core concepts
| Piece | Role |
|---|---|
| Controlled value | value + onChange |
| Single source of truth | State owns the string |
| Validation | Derive errors from state |
| Submit handler | Read state, not DOM |
💡 Examples
ControlledInput.tsx:
import { FormEvent, useState } from "react";
export function NameForm({ onSave }: { onSave: (name: string) => void }) {
const [name, setName] = useState("");
const error = name.trim().length === 0 ? "Name is required" : null;
function handleSubmit(event: FormEvent) {
event.preventDefault();
if (error) return;
onSave(name.trim());
setName("");
}
return (
<form onSubmit={handleSubmit}>
<label htmlFor="name">Name</label>
<input
id="name"
value={name}
onChange={(e) => setName(e.target.value)}
aria-invalid={Boolean(error)}
aria-describedby={error ? "name-error" : undefined}
/>
{error ? (
<p id="name-error" role="alert">
{error}
</p>
) : null}
<button type="submit" disabled={Boolean(error)}>
Save
</button>
</form>
);
}⚠️ Pitfalls
- Mixing
defaultValueandvaluemakes the input semi-controlled — pick one. - For checkboxes use
checked, notvalue, as the controlled prop. - Resetting after submit should set state to
"", not touch the DOM.