Form Validation in React
Forms are useless if users can submit invalid data. **Form validation** ensures that the data meets your requirements before it's processed. In React, you can implement validation in several ways, from simple inline checks to dedicated validation libraries.
Types of Validation
- Client-side validation: Immediate feedback, better user experience, but not secure.
- Server-side validation: Essential for security, final check before processing.
Always validate on the server too! Client-side validation is for user experience, server-side validation is for security.
Basic Validation with Controlled Components
function ValidationForm() { const [formData, setFormData] = useState({ username: '', email: '', age: '' }); const [errors, setErrors] = useState({});
function validate(name, value) { switch (name) { case 'username': if (value.length < 3) { return 'Username must be at least 3 characters'; } if (value.length > 20) { return 'Username must be less than 20 characters'; } return ''; case 'email': if (value && !/^[^s@]+@[^s@]+.[^s@]+$/.test(value)) { return 'Invalid email format'; } return ''; case 'age': if (value && (parseInt(value) < 18 || parseInt(value) > 120)) { return 'Age must be between 18 and 120'; } return ''; default: return ''; } }
function handleChange(event) { const { name, value } = event.target; setFormData(prev => ({ ...prev, [name]: value })); <!-- Validate on change --> const error = validate(name, value); setErrors(prev => ({ ...prev, [name]: error })); }
function handleSubmit(event) { event.preventDefault(); <!-- Validate all fields before submit --> const newErrors = {}; Object.keys(formData).forEach(key => { const error = validate(key, formData[key]); if (error) newErrors[key] = error; }); if (Object.keys(newErrors).length === 0) { console.log('Form submitted:', formData); } else { setErrors(newErrors); } }
return ( <form onSubmit={handleSubmit}> <div> <input name="username" value={formData.username} onChange={handleChange} placeholder="Username" /> {errors.username && <span style={{ color: 'red' }}>{errors.username}</span>} </div> <div> <input name="email" type="email" value={formData.email} onChange={handleChange} placeholder="Email" /> {errors.email && <span style={{ color: 'red' }}>{errors.email}</span>} </div> <div> <input name="age" type="number" value={formData.age} onChange={handleChange} placeholder="Age" /> {errors.age && <span style={{ color: 'red' }}>{errors.age}</span>} </div> <button type="submit">Submit</button> </form> );}Using HTML5 Built-in Validation
HTML5 provides some built-in validation attributes that work in React too:
<input type="email" required minLength={5} maxLength={50} pattern="[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,}$"/>However, the default browser validation styling and behavior can be inconsistent. Most React developers prefer custom validation.
Real-time Validation with Debouncing
For API calls (like checking if a username is available), you don't want to call the API on every keystroke. Use debouncing:
import { useState, useEffect } from 'react';
function UsernameField() { const [username, setUsername] = useState(''); const [isAvailable, setIsAvailable] = useState(null); const [checking, setChecking] = useState(false);
useEffect(() => { const timer = setTimeout(() => { if (username.length >= 3) { setChecking(true); <!-- Simulate API call --> fetch(`/api/check-username?username=${username}`) .then(res => res.json()) .then(data => { setIsAvailable(data.available); setChecking(false); }); } }, 500); <!-- Wait 500ms after last keystroke -->
return () => clearTimeout(timer); }, [username]);
return ( <div> <input value={username} onChange={(e) => setUsername(e.target.value)} placeholder="Choose username" /> {checking && <span>Checking...</span>} {isAvailable === false && <span style={{ color: 'red' }}>Username taken</span>} {isAvailable === true && <span style={{ color: 'green' }}>Username available</span>} </div> );}Validation Libraries
For complex forms, consider using validation libraries:
- Formik: Popular form library with built-in validation
- React Hook Form: Performant form library with easy validation
- Yup: Schema validation library often used with Formik
Two Minute Drill
- Form validation ensures user input meets requirements before submission.
- Always validate on both client (UX) and server (security).
- Controlled components make validation easier – you have immediate access to values.
- Store errors in state and display them near the relevant inputs.
- For API validation (like checking username availability), use debouncing to avoid too many requests.
- For complex forms, consider using dedicated libraries like Formik or React Hook Form.
Need more clarification?
Drop us an email at career@quipoinfotech.com
