Forms
React · Reference cheat sheet
Forms
React · Reference cheat sheet
📋 Overview
React forms are controlled (state drives inputs) or uncontrolled (refs / default values). Prefer controlled for validation and conditional UI; uncontrolled for simple or large native forms. Prevent default submit and handle async saves carefully.
🔧 Core concepts
- Controlled —
value+onChangebound to state. - Uncontrolled —
defaultValue+ref/FormData. - Submit —
onSubmiton<form>;preventDefault(). - Checkbox/radio —
checked/selected; groups sharename. - Files — uncontrolled
type="file"; read viaFormData. - a11y —
label+useId, error text witharia-describedby.
💡 Examples
Controlled:
import { useState, FormEvent } from "react";
export function LoginForm({ onLogin }: { onLogin: (email: string) => void }) {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
function handleSubmit(e: FormEvent) {
e.preventDefault();
onLogin(email);
}
return (
<form onSubmit={handleSubmit}>
<label>
Email
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</label>
<label>
Password
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</label>
<button type="submit">Sign in</button>
</form>
);
}FormData (uncontrolled):
function handleSubmit(e: FormEvent<HTMLFormElement>) {
e.preventDefault();
const data = new FormData(e.currentTarget);
console.log(data.get("email"));
}⚠️ Pitfalls
- Mixing
valuewithoutonChange→ read-only warning. - Using
value=\{undefined\}then string → uncontrolled→controlled switch. - Mutating state in place for nested form objects.
- Blocking submit button without keyboard/
Enterconsiderations.
🔗 Related
- useState.md — field state
- useId.md — label ids
- useRef.md — uncontrolled refs
- events.md — handlers
- testing.md — user-event