Регистрация в React с Formik и Yup

Formik — это библиотека управления формами для React, которая предоставляет компоненты и хуки для упрощения создания форм. Formik берёт на себя управление состояниями формы, валидацией и обработкой ошибок, что облегчает сбор и хранение данных пользователя.
В этом руководстве вы шаг за шагом создадите форму регистрации в React с использованием Formik. Чтобы следовать материалу, требуется базовое понимание React-хуков.
Что мы будем делать
- Создадим новое приложение React через create-react-app.
- Добавим библиотеку Formik и настроим useFormik.
- Реализуем валидацию вручную и через Yup.
- Отобразим ошибки и поведение при blur/submit.
- Обсудим альтернативные подходы, тестирование и безопасность.
Создание проекта React
Используйте create-react-app для создания нового проекта:
npx create-react-app formik-formПерейдите в папку проекта и откройте src. Удалите всё, кроме App.js. Затем создайте файл Register.js — в нём будет компонент формы. Не забудьте импортировать Register в App.js.
Контролируемые и неконтролируемые компоненты
React поддерживает два подхода к управлению формами:
- Контролируемые компоненты: значения полей хранятся в состоянии React (useState или похожие инструменты). Это даёт полный контроль и предсказуемость.
- Неконтролируемые компоненты: данные формы читаются из DOM с помощью ref. Подход проще для простых форм, но сложнее при сложной логике и валидации.
Официальная рекомендация — использовать контролируемые компоненты для сложных форм. Formik делает контролируемые формы компактнее и удобнее.
Пример контролируемой формы без Formik
import { useState } from "react";
const Register = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const handleSubmit = (event) => {
event.preventDefault();
console.log({ email, password });
};
return (
);
};
export default Register;Этот код работоспособен, но быстро усложняется по мере добавления полей, валидации и обработки ошибок.
Почему Formik
Formik снижает шаблонность кода при управлении состоянием формы, связывает значения, обработчики onChange/onBlur и обработчик submit. Формы становятся короче и чище — при этом сохраняется полная гибкость.
Добавление Formik в проект
Установите библиотеку:
npm install formikВ файле Register.js импортируйте хук useFormik:
import { useFormik } from "formik";Инициализируйте форму с начальными значениями и обработчиком onSubmit:
const formik = useFormik({
initialValues: {
email: "",
password: "",
},
onSubmit: (values) => {
// Здесь вы обрабатываете сабмит, напр., отправляете данные на сервер
console.log("submitted", values);
},
});Подключение полей формы к Formik
Чтобы связать поля с Formik, используйте formik.values, formik.handleChange, formik.handleBlur и formik.handleSubmit:
Кнопка сабмита вызывает formik.handleSubmit, который передаёт значения в onSubmit.
Валидация формы вручную
Formik принимает функцию validate, которая получает текущие values и должна вернуть объект ошибок, где ключи — имена полей.
const formik = useFormik({
initialValues: { email: "", password: "" },
validate: (values) => {
const errors = {};
if (!values.email) {
errors.email = "Обязательное поле";
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)) {
errors.email = "Неверный формат email";
}
if (!values.password) {
errors.password = "Обязательное поле";
} else if (values.password.length < 8) {
errors.password = "Пароль должен быть не менее 8 символов";
}
return errors;
},
onSubmit: (values) => {
console.log("submitted", values);
},
});Важно: validate запускается при изменениях и при submit; Formik хранит ошибки в formik.errors.
Отображение ошибок и touched
Чтобы не показывать ошибки до первого взаимодействия с полем, используйте formik.touched:
Валидация через Yup
Formik хорошо интегрируется с Yup — библиотекой для схемной валидации. Она упрощает описание правил и делает код чище.
Установите Yup:
npm install yupИмпортируйте и определите схему валидации:
import * as Yup from "yup";
const validationSchema = Yup.object().shape({
email: Yup.string()
.email("Неверный формат email")
.required("Обязательное поле"),
password: Yup.string()
.min(8, "Пароль должен быть не менее 8 символов")
.required("Обязательное поле"),
});
const formik = useFormik({
initialValues: { email: "", password: "" },
validationSchema,
onSubmit: (values) => {
console.log("submitted", values);
},
});Yup позволяет легко расширять валидацию (подтверждение пароля, регулярные выражения, кастомные тесты).
Улучшения UX
- Показывайте индикацию загрузки при отправке на сервер (formik.isSubmitting).
- Ставьте aria-атрибуты: aria-invalid на ошибочных полях и aria-describedby, чтобы связать поле с элементом ошибки.
- Для критически важных полей отображайте подсказки формата (например, минимальная длина пароля) ещё до ввода.
Альтернативные подходы
- React Hook Form — более лёгкая библиотека по производительности и объёму кода, особенно для больших динамических форм. Подходит, когда важна производительность при множестве полей.
- Использование controlled components вручную — полезно для очень простых форм или при специфичных потребностях.
- Использование UI-форм-шаблонов (Formik + UI-библиотеки) — быстрый способ получить стилизованные поля.
Когда Formik может не подойти
- Очень большие формы с сотнями полей: Formik держит состояние в компоненте и может вызывать лишние рендеры. React Hook Form использует refs и может быть эффективнее.
- Если нужна минимальная зависимость от внешних библиотек или вы хотите полностью контролировать производительность — ручная реализация или React Hook Form предпочтительнее.
Тестирование и критерии приёмки
Рекомендуемые тест-кейсы:
- Успешная отправка с корректными email и паролем.
- Отображение ошибок при пустых полях.
- Ошибка при коротком пароле.
- Ошибка при неверном формате email.
- Поведение after blur: ошибка появляется только после blur.
Критерии приёмки:
- При корректных данных форма отправляет значения в onSubmit.
- Неправильные значения показывают понятные сообщения об ошибке.
- UI доступен: поля имеют aria-атрибуты, ошибки читаются скрин-ридерами.
Безопасность и конфиденциальность
- Никогда не храните пароли в локальном хранилище (localStorage/sessionStorage) в открытом виде.
- Отправляйте данные только по HTTPS.
- На сервере храните пароли в виде хэша (bcrypt или Argon2). Формы в стороне клиента служат только для валидации и UX.
- Минимизируйте логи: не выводите реальные пароли в консоль на продакшне.
- При обработке ошибок на сервере не давайте слишком детальную информацию, чтобы не раскрывать внутреннюю логику.
Рольовые чек-листы
Для фронтенда:
- Подключён Formik и схема Yup (если используется).
- Поля связаны с formik.values, handleChange, handleBlur.
- Обработаны состояния isSubmitting и ошибки.
- Добавлены aria-метки и семантические элементы.
Для бэкенда:
- Проверка и валидация данных на сервере обязательны.
- Пароли хранятся в виде хэша.
- Ограничение скорости запросов и защита от брутфорса.
Для QA:
- Провести тесты из раздела тест-кейсов.
- Проверить работоспособность на мобильных браузерах.
Мини-методология внедрения в проект
- Прототип: реализовать простую форму с начальной валидацией.
- Схема: определить поля, правила валидации и ошибки для пользователя.
- Интеграция: подключить Formik + Yup и реализовать onSubmit с моком API.
- Тесты: написать unit/интеграционные тесты для основных сценариев.
- Рефакторинг: при необходимости заменить часть логики на React Hook Form, если есть проблемы с производительностью.
Пример готового компонента Register.js (с комментариями)
import React from "react";
import { useFormik } from "formik";
import * as Yup from "yup";
const Register = () => {
const validationSchema = Yup.object().shape({
email: Yup.string().email("Неверный формат email").required("Обязательное поле"),
password: Yup.string().min(8, "Пароль должен быть не менее 8 символов").required("Обязательное поле"),
});
const formik = useFormik({
initialValues: { email: "", password: "" },
validationSchema,
onSubmit: async (values, { setSubmitting, resetForm }) => {
setSubmitting(true);
try {
// пример отправки на сервер
// await api.register(values);
console.log("Submitted:", values);
resetForm();
} catch (err) {
// Обработка ошибок сервера
console.error(err);
} finally {
setSubmitting(false);
}
},
});
return (
);
};
export default Register;Советы по миграции на production
- Логируйте только необходимые события, не храните пароли в логах.
- Используйте механизмы защиты от CSRF и CORS на стороне сервера.
- Включите rate limiting для защитных точек регистрации.
Короткое резюме
Formik упрощает работу с формами в React: он снижает количество шаблонного кода, объединяет значения, обработчики и валидацию. Yup делает валидацию декларативной и удобной для расширения. Для очень больших форм рассмотрите альтернативы вроде React Hook Form.
Важно: всегда валидируйте данные и на клиенте, и на сервере, и соблюдайте базовые практики безопасности.
Полезные ссылки
- Документация Formik — официальный источник по API и хукам.
- Документация Yup — справочник по схемам валидации.
Резюме:
- Formik помогает управлять состоянием форм и ошибками.
- Yup упрощает валидацию через схемы.
- Тестируйте сценарии ошибок и успеха.
- Не забывайте про безопасность и server-side валидацию.
Похожие материалы
Как покупать NFT на Solana — шаги и безопасность
Заполнение букв в Procreate: цвет и изображение
Удалить изученные слова на клавиатуре Android
Как исправить: Точка доступа временно заполнена
Исправить XBOX_ERACTRL_CS_TIMEOUT (0x356)