Formik — это популярная библиотека для управления состоянием форм в React-приложениях. Она упрощает обработку данных формы, валидацию и интеграцию с UI-компонентами. Formik позволяет избегать громоздкого ручного управления состоянием и обработчиков событий, делая код чище и более предсказуемым.
Для начала работы необходимо импортировать Formik и
Form из библиотеки:
import { Formik, Form, Field, ErrorMessage } from 'formik';
Базовый пример формы:
<Formik
initialValues={{ email: '', password: '' }}
onSub mit={(values) => {
console.log(values);
}}
>
{({ isSubmitting }) => (
<Form>
<div>
<label htmlFor="email">Email</label>
<Field type="email" name="email" />
<ErrorMessage name="email" component="div" />
</div>
<div>
<label htmlFor="password">Пароль</label>
<Field type="password" name="password" />
<ErrorMessage name="password" component="div" />
</div>
<button type="submit" disabled={isSubmitting}>
Отправить
</button>
</Form>
)}
</Formik>
Ключевые моменты:
initialValues задает начальное состояние полей
формы.Field автоматически связывает поле ввода с состоянием
Formik.ErrorMessage отображает ошибки валидации, если они
существуют.isSubmitting показывает состояние отправки формы.Formik поддерживает синхронную и асинхронную валидацию. Наиболее
популярный способ — использование библиотеки Yup:
import * as Yup from 'yup';
const validationSchema = Yup.object({
email: Yup.string().email('Неверный формат email').required('Обязательное поле'),
password: Yup.string().min(6, 'Минимум 6 символов').required('Обязательное поле'),
});
В Formik это подключается через свойство
validationSchema:
<Formik
initialValues={{ email: '', password: '' }}
validationSchema={validationSchema}
onSub mit={(values) => console.log(values)}
>
Formik предоставляет удобные методы для работы с полями и состоянием формы:
setFieldValue(name, value) — программное изменение
значения поля.setFieldTouched(name, touched) — установка состояния
«прикосновения» к полю.resetForm() — сброс формы к начальным значениям.Кастомные компоненты удобно интегрировать через useField
хук:
import { useField } from 'formik';
const TextInput = ({ label, ...props }) => {
const [field, meta] = useField(props);
return (
<div>
<label htmlFor={props.id || props.name}>{label}</label>
<input {...field} {...props} />
{meta.touched && meta.error ? <div>{meta.error}</div> : null}
</div>
);
};
Использование:
<Formik initialValues={{ username: '' }} onSub mit={console.log}>
<Form>
<TextInput label="Имя пользователя" name="username" type="text" />
<button type="submit">Отправить</button>
</Form>
</Formik>
Formik отлично справляется с массивами полей с помощью компонента
FieldArray. Пример:
import { FieldArray } from 'formik';
<FieldArray name="friends">
{({ push, remove, form }) => (
<div>
{form.values.friends.map((friend, index) => (
<div key={index}>
<Field name={`friends.${index}.name`} placeholder="Имя друга" />
<button type="button" onCl ick={() => remove(index)}>Удалить</button>
</div>
))}
<button type="button" onCl ick={() => push({ name: '' })}>Добавить друга</button>
</div>
)}
</FieldArray>
Особенности:
push() добавляет новый элемент в массив.remove() удаляет элемент по индексу.Formik поддерживает асинхронную обработку:
<Formik
initialValues={{ username: '' }}
validate={async (values) => {
const errors = {};
const isAvailable = await checkUsernameAvailability(values.username);
if (!isAvailable) errors.username = 'Имя пользователя занято';
return errors;
}}
onSub mit={async (values, { setSubmitting }) => {
await sendFormData(values);
setSubmitting(false);
}}
>
Важно: всегда управлять состоянием
isSubmitting, чтобы предотвратить многократную отправку
формы.
Formik легко интегрируется с компонентами Radix UI, Material UI или
Chakra UI через кастомные поля и хук useField. Пример с
Radix UI:
import * as Switch from '@radix-ui/react-switch';
import { useField } from 'formik';
const FormSwitch = ({ name }) => {
const [field, , helpers] = useField(name);
return (
<Switch.Root
checked={field.value}
onCheckedCha nge={(val) => helpers.setValue(val)}
>
<Switch.Thumb />
</Switch.Root>
);
};
Formik позволяет работать с глубоко вложенными данными с помощью точечной нотации:
initialValues={{
user: { firstName: '', lastName: '' },
}}
<Field name="user.firstName" />
<Field name="user.lastName" />
Ошибки и валидация поддерживают такую же структуру, позволяя точно указывать путь к полю.
useFormikContext() — доступ к контексту формы в любом
компоненте.useField(name) — управление отдельным полем с
метаданными.useFormik() — полный доступ к методам и состоянию формы
для кастомной логики.Formik предоставляет полный набор инструментов для управления формами в React: автоматическое связывание полей, валидация, поддержка массивов, асинхронных действий и интеграция с внешними UI-библиотеками. Его гибкая архитектура позволяет создавать как простые формы, так и сложные динамические структуры с минимальным количеством повторяющегося кода.