Form validation ensures data integrity before submission.
Manual validation:
1import { useState } from "react";23interface FormData {4 email: string;5 password: string;6}78interface Errors {9 email?: string;10 password?: string;11}1213function RegistrationForm() {14 const [formData, setFormData] = useState<FormData>({ email: "", password: "" });15 const [errors, setErrors] = useState<Errors>({});1617 const validate = (): boolean => {18 const newErrors: Errors = {};1920 if (!formData.email) {21 newErrors.email = "Email is required";22 } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {23 newErrors.email = "Invalid email format";24 }2526 if (!formData.password) {27 newErrors.password = "Password is required";28 } else if (formData.password.length < 8) {29 newErrors.password = "Password must be at least 8 characters";30 }3132 setErrors(newErrors);33 return Object.keys(newErrors).length === 0;34 };3536 const handleSubmit = (e: React.FormEvent) => {37 e.preventDefault();38 if (validate()) {39 console.log("Submit:", formData);40 }41 };4243 return (44 <form onSubmit={handleSubmit}>45 <div>46 <input47 type="email"48 value={formData.email}49 onChange={e => setFormData(prev => ({ ...prev, email: e.target.value }))}50 />51 {errors.email && <span className="error">{errors.email}</span>}52 </div>53 <div>54 <input55 type="password"56 value={formData.password}57 onChange={e => setFormData(prev => ({ ...prev, password: e.target.value }))}58 />59 {errors.password && <span className="error">{errors.password}</span>}60 </div>61 <button type="submit">Register</button>62 </form>63 );64}
With React Hook Form:
1import { useForm } from "react-hook-form";2import { zodResolver } from "@hookform/resolvers/zod";3import { z } from "zod";45const schema = z.object({6 email: z.string().email("Invalid email"),7 password: z.string().min(8, "Password must be at least 8 characters"),8});910type FormData = z.infer<typeof schema>;1112function RegistrationForm() {13 const { register, handleSubmit, formState: { errors } } = useForm<FormData>({14 resolver: zodResolver(schema),15 });1617 const onSubmit = (data: FormData) => console.log(data);1819 return (20 <form onSubmit={handleSubmit(onSubmit)}>21 <input {...register("email")} />22 {errors.email && <span>{errors.email.message}</span>}23 <input {...register("password")} type="password" />24 {errors.password && <span>{errors.password.message}</span>}25 <button type="submit">Register</button>26 </form>27 );28}