Advanced Forms
Complex form patterns in React — validation, controlled inputs, and libraries
What you'll learn
Build accessible forms with proper semantic HTML structure
Implement client-side validation with Constraint Validation API
Create custom validation UX with real-time feedback and error messages
Handle form submission with loading states and optimistic updates
Structure complex multi-step forms with progress tracking and data persistence
Apply progressive enhancement so forms work without JavaScript
Forms are a critical UI pattern. Learn to build them well in React.
Controlled Components
React controls form state via state variables:
"use client"
import { useState } from "react"
export default function LoginForm() {
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
console.log({ email, password })
}
return (
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label htmlFor="email">Email</label>
<input
id="email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full rounded border p-2"
required
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full rounded border p-2"
required
/>
</div>
<button
type="submit"
className="rounded bg-blue-500 px-4 py-2 text-white"
>
Login
</button>
</form>
)
}
Validation Pattern
interface Errors {
email?: string
password?: string
}
function validate(values: { email: string; password: string }): Errors {
const errors: Errors = {}
if (!values.email.includes("@")) errors.email = "Invalid email"
if (values.password.length < 6) errors.password = "Too short"
return errors
}
Next Steps
Key Takeaways
Semantic HTML form elements provide built-in accessibility and validation
The Constraint Validation API enables native client-side validation without JavaScript
Custom validation UX should provide real-time feedback, clear error messages, and focus management
Multi-step forms benefit from progress indicators, back navigation, and intermediate data persistence
Progressive enhancement ensures forms remain functional even when JavaScript fails to load
Optimistic updates create a responsive feel but require rollback logic for failed submissions