Формы и валидация (React)
Формы с «ручным» контролем состояния перерисовывают всю форму на каждую букву. React Hook Form рендерит только изменённое поле, а zod даёт типизируемую валидацию на сервере и клиенте.
RHF + zod
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
const schema = z.object({
email: z.string().email("Некорректный email"),
password: z.string().min(8, "Минимум 8 символов")
});
function Signup() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(schema)
});
return (
<form onSubmit={handleSubmit(async (data) => await api.signup(data))}>
<input {...register("email")} />
{errors.email && <p>{errors.email.message}</p>}
<button type="submit">Создать</button>
</form>
);
}
💡
Одна схема zod на сервере и клиенте (в shared/) — и фронт с бэком «договариваются» сами: типы выводятся из z.infer. Никакой рассинхронизации валидации.
Почему это важно
- быстрый ввод: поле контролируется, но форма не перерисовывается целиком;
- ошибки показываются после blur or submit, без спама на каждую букву;
- z.infer автоматически выводит типы из схемы;
- всё это работает и с TS (урок 26), и с UI-китами.
ℹ️
Серверная валидация обязательна всегда — клиентской не верьте. На бэке та же zod-схема, что и на фронте, проверяет тело запроса до бизнес-логики.