React Form Validation with Custom Hook
Validate React form fields using a custom useForm hook with real-time error messages, submission blocking, and TypeScript type safety for form data and.
Code
import { useState, useCallback } from 'react';
interface ValidationRule {
required?: boolean;
minLength?: number;
pattern?: RegExp;
message: string;
}
export function useForm<T extends Record<string, string>>(
initialValues: T,
rules: Partial<Record<keyof T, ValidationRule[]>>,
) {
const [values, setValues] = useState(initialValues);
const [errors, setErrors] = useState<Partial<Record<keyof T, string>>>({});
const validate = useCallback(
(name: keyof T, value: string) => {
const fieldRules = rules[name];
if (!fieldRules) return '';
for (const rule of fieldRules) {
if (rule.required && !value) return rule.message;
if (rule.minLength && value.length < rule.minLength) return rule.message;
if (rule.pattern && !rule.pattern.test(value)) return rule.message;
}
return '';
},
[rules],
);
const handleChange = (name: keyof T, value: string) => {
setValues((prev) => ({ ...prev, [name]: value }));
setErrors((prev) => ({ ...prev, [name]: validate(name, value) }));
};
const isValid = Object.keys(rules).every((key) => !validate(key as keyof T, values[key as keyof T]));
return { values, errors, handleChange, isValid };
}