Формы являются неотъемлемой частью того, как пользователи взаимодействуют с нашими веб-сайтами и веб-приложениями. Проверка данных, которые пользователь передает в форму, важна для нашей работы как веб-разработчиков. Formik — это бесплатная легкая библиотека форм с открытым исходным кодом для React. Formik создан для масштабируемости и высокой производительности: инструмент форм с минимальным API, который позволяет разработчикам создавать поля форм с меньшим количеством кода.
Formik — это гибкая библиотека форм. Это позволяет вам решать, когда и сколько вы хотите его использовать. Мы можем контролировать объем используемой функциональности библиотеки Formik. Конечно, его можно использовать с полями ввода HTML и пользовательскими проверками с помощью yup. Он был разработан Джаредом Палмером во время работы над полем формы для своего проекта в поисках стандартизации компонентов ввода и потока отправки формы. Идея заключалась в том, чтобы все было организовано и в одном месте. Formik обращается к трем ключевым моментам:
- Получение значений в состоянии формы и вне его
- Проверка и сообщения об ошибках
- Обработка отправки формы
Мы учтем все эти моменты при сборке примера React-приложения — и в качестве бонуса увидим пример валидации, выполненной с библиотекой Yup.
Введение
Прежде чем мы узнаем, как использовать Formik, давайте сделаем небольшое введение и посмотрим, как Formik работает с простой формой информационного бюллетеня. Представьте, что мы хотим добавить форму подписки на новостную рассылку для блога. Начнем с того, что в нашей форме будет только одно поле с именем email. С Formik это всего несколько строк кода.
import React from 'react';
import { useFormik } from 'formik';
const SignupForm = () => {
// Pass the useFormik() hook initial form values and a submit function that will
// be called when the form is submitted
const formik = useFormik({
initialValues: {
email: '',
},
onSubmit: values => {
alert(JSON.stringify(values, null, 2));
},
});
return (
<form onSubmit={formik.handleSubmit}>
<label htmlFor="email">Email Address</label>
<input
id="email"
name="email"
type="email"
onChange={formik.handleChange}
value={formik.values.email}
/>
<button type="submit">Submit</button>
</form>
);
};
Мы передаем initialValues
нашей формы и функцию отправки ( onSubmit
) в хук useFormik()
. Хук возвращает нам пакет с состоянием формы и вспомогательными методами в переменной, которую мы называем formik
. На данный момент единственные вспомогательные методы, которые нас интересуют, следующие:
Как вы можете видеть выше, мы передаем каждый из них в соответствующий реквизит… и все! Теперь у нас может быть рабочая форма на базе Formik. Вместо того, чтобы самостоятельно управлять значениями нашей формы и писать собственные обработчики событий для каждого отдельного ввода, мы можем просто useFormik().
Преимущества Формика
Каковы преимущества использования Formik?
- Масштабируемость: Formik хорошо подходит для комплексного решения, включая проверку и обработку отправки форм; мы также можем сохранить состояние формы локализованным и управляемым Formik, что подходит для создания многошаговых форм.
- Размер. Размер был одним из самых значительных преимуществ Formik; с уменьшенным размером 12,7 КБ в gzip-архиве Formik по-прежнему может архивировать состояние формы с минимальными API.
- Дополнительные пакеты: Formik расширяет свои возможности, позволяя использовать дополнительные пакеты. Можно интегрировать Yup с Formik для проверки или, используя Redux State Management, вы также можете реализовать Formik для своего состояния формы (что невозможно, когда речь идет о форме Redux).
Кроме того, давайте сравним Formik с другими инструментами форм с самым высоким рейтингом в React с точки зрения их производительности, опыта разработки, компонентов, шаблонов, конкурса популярности и многого другого.
- Интеграция. Библиотека форм, такая как Redux Form, не допускает интеграции, в отличие от Formik/React Hook Form. Formik и React Hook Form могут интегрироваться с любым сторонним приложением (особенно Yup и Redux) для проверки, и вы также можете использовать входные данные HTML5 с Formik для поля формы.
- Шаблон. Шаблон — это то, чем разработчики не хотят заниматься. Библиотеки инструментов форм, такие как Redux Form/Final Form, сталкиваются с этими проблемами, представьте, что вам нужно использовать инструмент формы, такой как Final Form, и все место покрыто шаблоном; Думаю, это не лучший способ начать форму. С другой стороны, Formik и React Hook Form составляют меньше шаблонов в вашем коде.
- Конкурс популярности. Для конкурса популярности мы составим таблицу со всеми вышеперечисленными библиотеками форм и сравним их в соответствии с их звездами Github/форками/еженедельной загрузкой/размером.
С данными, которые у нас есть выше, кажется, что Formik лидирует в гонке с более чем 30 тысячами звезд Github и, что наиболее важно, более 2 миллионов загрузок в неделю, что является огромной победой для Formik. Formik — отличный инструмент для работы, хотя остальные библиотеки также имеют хорошие возможности.
Создайте страницу регистрации с помощью Formik и Yup Validation
Чтобы полностью понять это руководство, убедитесь, что вы знакомы с React и у вас установлены последние версии Node и npm.
Начнем с создания нашего проекта. Перейдите к своему терминалу и выполните следующую команду;
npx create-react-app formik-form
Кроме того, чтобы мы могли использовать Formik в качестве инструмента для форм, нам нужно установить его зависимости с помощью следующей команды;
cd formik-form
npm install formik --save
npm install yup --save
npm start
Мы создадим формы входа и регистрации, чтобы показать, как использовать Formik, и добавим Yup для проверки.
Создание компонента регистрации
Мы создадим компонент регистрации, чтобы принимать имя, адрес электронной почты и пароль.
import { useFormik } from "formik";
import { basicSchema } from "../schema";
const onSubmit = async (values, actions) => {
console.log(values);
console.log(actions);
await new Promise((resolve) => setTimeout(resolve, 1000));
actions.resetForm();
};
const SignUp = () => {
const {
values,
errors,
touched,
isSubmitting,
handleBlur,
handleChange,
handleSubmit,
} = useFormik({
initialValues: {
firstname: "",
lastname: "",
email: "",
age: "",
password: "",
confirmPassword: "",
},
validationSchema: basicSchema,
onSubmit,
});
console.log(errors);
return (
<form onSubmit={handleSubmit} autoComplete="off">
<label htmlFor="firstname">First Name</label>
<input
value={values.firstname}
onChange={handleChange}
id="firstname"
type="firstname"
placeholder="Enter First Name"
onBlur={handleBlur}
className={errors.firstname && touched.firstname ? "input-error" : ""}
/>
{errors.firstname && touched.firstname && <p className="error">{errors.firstname}</p>}
<label htmlFor="lastname">Last Name</label>
<input
value={values.lastname}
onChange={handleChange}
id="lastname"
type="lastname"
placeholder="Enter Last Name"
onBlur={handleBlur}
// className={errors.email && touched.email ? "input-error" : ""}
/>
{errors.lastname && touched.lastname && <p className="error">{errors.lastname}</p>}
<label htmlFor="email">Email</label>
<input
value={values.email}
onChange={handleChange}
id="email"
type="email"
placeholder="Enter your email"
onBlur={handleBlur}
className={errors.email && touched.email ? "input-error" : ""}
/>
{errors.email && touched.email && <p className="error">{errors.email}</p>}
<label htmlFor="age">Age</label>
<input
id="age"
type="number"
placeholder="Enter your age"
value={values.age}
onChange={handleChange}
onBlur={handleBlur}
className={errors.age && touched.age ? "input-error" : ""}
/>
{errors.age && touched.age && <p className="error">{errors.age}</p>}
<label htmlFor="password">Password</label>
<input
id="password"
type="password"
placeholder="Enter your password"
value={values.password}
onChange={handleChange}
onBlur={handleBlur}
className={errors.password && touched.password ? "input-error" : ""}
/>
{errors.password && touched.password && (
<p className="error">{errors.password}</p>
)}
<label htmlFor="confirmPassword">Confirm Password</label>
<input
id="confirmPassword"
type="password"
placeholder="Confirm password"
value={values.confirmPassword}
onChange={handleChange}
onBlur={handleBlur}
className={
errors.confirmPassword && touched.confirmPassword ? "input-error" : ""
}
/>
{errors.confirmPassword && touched.confirmPassword && (
<p className="error">{errors.confirmPassword}</p>
)}
<button disabled={isSubmitting} type="submit">
Submit
</button>
</form>
);
};
export default SignUp;
Эта форма включает поля имени и фамилии, адреса электронной почты, возраста, пароля и подтверждения пароля.
Пользовательский компонент ввода
В CustomInput
мы будем использовать useField
, пользовательский хук React, который позволит подключать входные данные к formik.
import { useField } from "formik";
const CustomInput = ({ label, ...props }) => {
const [field, meta] = useField(props);
return (
<>
<label>{label}</label>
<input
{...field}
{...props}
className={meta.touched && meta.error ? "input-error" : ""}
/>
{meta.touched && meta.error && <div className="error">{meta.error}</div>}
</>
);
};
export default CustomInput;
В CustomInput
useField()
возвращает [formik.getFieldProps(), formik.getFieldMeta()], которые мы можем распространить на <input>
. Мы можем использовать метаданные поля, чтобы показать сообщение об ошибке, если поле недействительно и к нему прикоснулись (т.е. посетили). Мы также создали такие компоненты для наших CustomCheckbox
и CustomSelect
. Цель состоит в том, чтобы сделать компонент повторно используемым в других частях нашего кода.
Компонент входа
Создайте компонент входа, чтобы принимать электронные письма и пароли, и флажок для подтверждения.
import { Form, Formik } from "formik";
import { advancedSchema } from "../schema";
import CustomCheckbox from "./CustomCheckbox";
import CustomInput from "./CustomInput";
const onSubmit = async (values, actions) => {
await new Promise((resolve) => setTimeout(resolve, 1000));
actions.resetForm();
};
const SignIn = () => {
return (
<Formik
initialValues={{ username: "", password: "", jobType: "", acceptedTos: false }}
validationSchema={advancedSchema}
onSubmit={onSubmit}
>
{({ isSubmitting }) => (
<Form>
<CustomInput
label="Username"
name="username"
type="text"
placeholder="Enter Username"
/>
<CustomInput
label="Password"
name="password"
type="text"
placeholder="Enter Password "
/>
<CustomCheckbox type="checkbox" name="acceptedTos" />
<button disabled={isSubmitting} type="submit">
Submit
</button>
</Form>
)}
</Formik>
);
};
export default SignIn;
Повтор сеанса с открытым исходным кодом
OpenReplay – это пакет для воспроизведения сеансов с открытым исходным кодом, который позволяет вам видеть, что пользователи делают в вашем веб-приложении, помогая вам быстрее устранять неполадки. OpenReplay размещается на собственном сервере для полного контроля над вашими данными.
Начните получать удовольствие от отладки — начните использовать OpenReplay бесплатно.
Реализация макета
Хотя здесь мы можем использовать любые библиотеки пользовательского интерфейса, такие как Bootstrap, Material UI или Chakra UI, мы создадим файл CSS, чтобы немного упростить задачу.
.App {
text-align: center;
padding: 5rem 1rem;
}
.error {
color: #fc8181;
font-size: 0.75rem;
text-align: left;
margin-top: 0.25rem;
nav {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 2rem;
}
nav h3 {
margin: 1rem;
cursor: pointer;
color: #718096;
}
nav h3:hover {
color: white;
}
form {
width: 95%;
max-width: 400px;
margin: 0 auto;
}
form label {
font-size: 1rem;
font-weight: bold;
display: block;
text-align: left;
margin: 1rem 0 0.2rem;
}
input,
select {
width: 100%;
padding: 0.65rem 0.5rem;
font-size: 1rem;
color: white;
border: 2px solid #4a5568;
background-color: #2d3748;
border-radius: 10px;
outline: none;
}
input:focus,
select:focus {
border-color: #4299e1;
}
input::placeholder,
select::placeholder {
color: #a0aec0;
}
input[type="checkbox"] {
width: fit-content;
margin-right: 0.5rem;
transform: scale(1.25);
}
button {
display: block;
margin: 1rem 0;
padding: 0.35rem 0.5rem;
background-color: #4299e1;
color: #1a202c;
border: none;
border-radius: 3px;
width: 100%;
font-size: 1rem;
font-weight: bold;
cursor: pointer;
}
input.input-error,
select.input-error {
border-color: #fc8181;
}
button:disabled {
opacity: 0.35;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background: #29736e;
color: #f3f3f3;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}
Вот так выглядят наши регистрационные формы.
Формы SignUp и SignIn позволяют вводить ваше имя, возраст, пароль, адрес электронной почты и флажок. Далее мы собираемся создать проверки для наших форм, используя Yup.
Включить проверку формы с помощью Yup
Валидации похожи на правила, которых необходимо придерживаться при заполнении формы, чтобы обеспечить ввод правильных данных, и мы собираемся использовать стороннее приложение под названием Yup для проверки нашей формы.
import * as yup from "yup";
const passwordRules = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{5,}$/;
// min 5 characters, 1 upper case letter, 1 lower case letter, 1 numeric digit.
export const basicSchema = yup.object().shape({
firstname: yup.string()
.max(15, 'Must be 15 characters or less')
.required('Required'),
lastname: yup.string()
.max(20, 'Must be 20 characters or less')
.required('Required'),
email: yup.string().email("Please enter a valid email").required("Required"),
age: yup.number().positive().integer().required("Required"),
password: yup
.string()
.min(5)
.matches(passwordRules, { message: "Please create a stronger password" })
.required("Required"),
confirmPassword: yup
.string()
.oneOf([yup.ref("password"), null], "Passwords must match")
.required("Required"),
});
export const advancedSchema = yup.object().shape({
username: yup
.string()
.min(3, "Username must be at least 3 characters long")
.required("Required"),
jobType: yup
.string()
.oneOf(["designer", "developer", "manager", "other"], "Invalid Job Type")
.required("Required"),
acceptedTos: yup
.boolean()
.oneOf([true], "Please accept the terms of service"),
});
Если вы посмотрите на изображение выше, вы заметите красный предупреждающий знак, указывающий, что требуется; с нашей проверкой Yup мы можем установить входные данные по мере необходимости, и если эти места не заполнены, пользователь не сможет отправить форму.
Наша форма теперь полностью функциональна в том смысле, что при интеграции Formik с пользователями/клиентами проверки Yup будет отображаться всплывающий текст ошибки для заполнения необходимых данных.
Заворачивать
С Formik, создающим легкие, с меньшим количеством кода, масштабируемые формы стали проще. В этой статье мы рассмотрели важность наличия такой библиотеки форм, как Formik, которая значительно упрощает создание форм для разработчиков, которые также смогут реализовать пошаговый процесс создания формы с помощью Formik и использования Ага, как наша проверка. Для живого приложения нажмите здесь, также для исходного кода на GitHub.
Ресурсы
- Формик
- "Ага"
Первоначально опубликовано на https://dev.to 15 июня 2022 г.