Form Validation
Form Validation
Validation ensures that data meets your requirements before submission. React gives you flexibility to validate anywhere: on change, on blur, or on submit.
Validation Strategies
| Strategy | When it fires | Best for |
|---|---|---|
| On Submit | When the form is submitted | Simple forms, non-intrusive UX |
| On Blur | When a field loses focus | Showing errors after the user finishes typing |
| On Change | Every keystroke | Password strength meters, live character counts |
| Hybrid | Blur first, then change after first error | Best UX in production forms |
Custom Validation:
JSX — ValidatedForm.jsx
import { useState } from 'react'; // Pure validation function — lives outside component for easy testing function validate(fields) { const errors = {}; if (!fields.email || !fields.email.includes('@')) { errors.email = 'Enter a valid email address'; } if (!fields.password || fields.password.length < 8) { errors.password = 'Password must be at least 8 characters'; } if (fields.password !== fields.confirm) { errors.confirm = 'Passwords do not match'; } return errors; // Empty object = no errors = valid } function ValidatedForm() { const [fields, setFields] = useState({ email: '', password: '', confirm: '' }); const [errors, setErrors] = useState({}); const [submitted, setSubmitted] = useState(false); const handleChange = (e) => { const { name, value } = e.target; const updated = { ...fields, [name]: value }; setFields(updated); if (submitted) setErrors(validate(updated)); // Live re-validate }; const handleSubmit = (e) => { e.preventDefault(); setSubmitted(true); const errs = validate(fields); setErrors(errs); if (Object.keys(errs).length === 0) { console.log('Valid! Sending to API:', fields); } }; const ErrorMsg = ({ field }) => errors[field] ? <span style={{ color: '#a02020', fontSize: '13px' }}>{errors[field]}</span> : null; return ( <form onSubmit={handleSubmit}> <input name="email" value={fields.email} onChange={handleChange} type="email" placeholder="Email" /> <ErrorMsg field="email" /> <input name="password" value={fields.password} onChange={handleChange} type="password" placeholder="Password" /> <ErrorMsg field="password" /> <input name="confirm" value={fields.confirm} onChange={handleChange} type="password" placeholder="Confirm password" /> <ErrorMsg field="confirm" /> <button type="submit">Sign Up</button> </form> ); } export default ValidatedForm;
