21. Form: валидация
Стратегии валидации
Заголовок раздела «Стратегии валидации»TanStack Form поддерживает валидацию на разных событиях:
<form.Field name="email" validators={{ onChange: ({ value }) => validateEmail(value), // При каждом вводе onBlur: ({ value }) => strictValidate(value), // При потере фокуса onMount: ({ value }) => initialValidate(value), // При монтировании onSubmit: ({ value }) => finalValidate(value), // При отправке onChangeAsync: async ({ value }) => await checkEmail(value), // Асинхронно при вводе onChangeAsyncDebounceMs: 500, // Дебаунс для async }}>Синхронная валидация
Заголовок раздела «Синхронная валидация»validators={{ onChange: ({ value }) => { if (!value) return 'Обязательное поле' if (value.length < 3) return 'Минимум 3 символа' if (value.length > 50) return 'Максимум 50 символов' return undefined // undefined = нет ошибки },}}Асинхронная валидация
Заголовок раздела «Асинхронная валидация»Идеальна для проверок на сервере (уникальность email, username):
validators={{ onChangeAsync: async ({ value }) => { if (!value) return undefined // Не проверяем пустые значения
const exists = await checkEmailExists(value) if (exists) return 'Этот email уже зарегистрирован'
return undefined }, onChangeAsyncDebounceMs: 500, // Ждём 500ms после ввода}}Валидация с Zod
Заголовок раздела «Валидация с Zod»import { z } from 'zod'
const userSchema = z.object({ name: z.string().min(2, 'Минимум 2 символа'), email: z.string().email('Невалидный email'), age: z.number().min(18, 'Минимальный возраст 18 лет'),})
// В useForm:const form = useForm({ defaultValues: { name: '', email: '', age: 0 }, validators: { onChange: userSchema, // Zod схема работает напрямую! },})Кросс-полевая валидация
Заголовок раздела «Кросс-полевая валидация»Валидация, которая зависит от значений других полей:
const form = useForm({ defaultValues: { password: '', confirmPassword: '' }, validators: { onChange: ({ value }) => { if (value.password !== value.confirmPassword) { return { fields: { confirmPassword: 'Пароли не совпадают' } } } }, },})Адаптеры валидации
Заголовок раздела «Адаптеры валидации»TanStack Form поддерживает популярные библиотеки через адаптеры:
import { zodValidator } from '@tanstack/zod-form-adapter'import { valibotValidator } from '@tanstack/valibot-form-adapter'
const form = useForm({ validatorAdapter: zodValidator(), validators: { onChange: z.object({ email: z.string().email(), }), },})errorMap и доступ к ошибкам
Заголовок раздела «errorMap и доступ к ошибкам»// Ошибки по источнику (errorMap — read-only, только для чтения)const errorMap = field.state.meta.errorMap// {// onChange: 'Ошибка при вводе',// onBlur: 'Ошибка при blur',// onSubmit: 'Ошибка при submit',// }
// Плоский массив всех ошибокfield.state.meta.errors // ['Ошибка при вводе', ...]