useFormValidation Hook
Lightweight form validation hook with field-level errors, touched tracking, and submit handling.
import { useState, useCallback } from 'react';
type Errors<T> = Partial<Record<keyof T, string>>;
type Validator<T> = (values: T) => Errors<T>;
export function useFormValidation<T extends Record<string, unknown>>(
initial: T,
validate: Validator<T>
) {
const [values, setValues] = useState(initial);
const [errors, setErrors] = useState<Errors<T>>({});
const [touched, setTouched] = useState<Partial<Record<keyof T, boolean>>>({});
const handleChange = useCallback(
(field: keyof T, value: T[keyof T]) => {
setValues((prev) => ({ ...prev, [field]: value }));
setTouched((prev) => ({ ...prev, [field]: true }));
},
[]
);
const handleSubmit = useCallback(
(onSubmit: (v: T) => void) => {
const errs = validate(values);
setErrors(errs);
if (Object.keys(errs).length === 0) onSubmit(values);
},
[values, validate]
);
return { values, errors, touched, handleChange, handleSubmit };
}Use Cases
- Contact forms
- Registration forms
- Settings pages
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
useLocalStorage — Persistent State Hook
Sync React state with localStorage including SSR safety, JSON serialization, and cross-tab updates.
usePrevious Hook
Track the previous value of any state or prop using a ref-based hook for comparison logic.
Server Action with Form Validation
Next.js Server Action handling form submissions with validation, error messages, and redirect on success.
useFetch — Generic Data Fetching Hook
Custom React hook for data fetching with loading, error, and refetch states using the Fetch API.