Скидки до 20% + 2-ая профессия бесплатно и подарки на 50 000₽

Главная | Все статьи | Код

Как создавать формы с помощью библиотеки Formik в React

JavaScript Время чтения статьи ~8 минут 16
Как создавать формы с помощью библиотеки Formik в React главное изображение

Рассказываем, как работает библиотека Formik для создания форм в React и почему мы рекомендуем ее использовать.

Эта статья больше подходит для тех, кто уже немного знает основы JS. Если вы еще не разобрались с ним, советуем перед прочтением пройти большую профессию по JavaScript на Хекслете.

Что такое Formik

Formik — это легкая, бесплатная библиотека с открытым исходным кодом для React или React Native, которая решает три основные задачи при создании форм:

  • Управление состоянием формы
  • Валидация формы
  • Отправка формы.

Библиотеку Formik написал директор по инструментам и платформам для разработчиков компании Vercel Джаред Палмер во время создания большой внутренней административной панели. Основная задача состояла в том, чтобы стандартизировать не только все формы, но и то, как через них проходят данные, что значительно упростило бы тестирование, рефакторинг и анализ этих форм.

Почему стоит использовать Formik

Создание формы только на React требует от разработчика самостоятельно написать каждую часть процесса: от настройки состояния до отправки формы. Программисту нужно будет учесть, что:

  • Нужно хранить и отслеживать значения полей формы, ошибки и статус валидации каждого поля
  • Потребуется обрабатывать ввод пользователя и менять состояние формы
  • Необходимо продумать и самостоятельно описать валидации
  • Нужно описать процесс отправки формы

Formik берет на себя все вышеперечисленные заботы и предоставляет ряд компонентов и хуков для создания форм в React и React Native. Далее в статье мы познакомимся с основными компонентами этой библиотеки: <Formik />, <Form />, <Field /> и <ErrorMessage />.

Как управлять состоянием формы в Formik

Для того, чтобы начать работать с Formik, достаточно обернуть форму в компонент <Formik />:

<Formik>
  <Form>
    {/* здесь остальной код */}
  </Form>
</Formik>

С помощью пропса initialValues мы инициализируем начальное состояние формы внутри Formik. При этом для того, чтобы получать значения и обновлять состояние полей формы, можно воспользоваться компонентом <Field /> вместо обычного HTML-элемента <input />. Этот компонент будет самостоятельно синхронизировать состояние, и нам не потребуется передавать через пропсы value и onChange:

<Formik
  initialValues={{ email: "", password: "" }}
  onSubmit={({ setSubmitting }) => {
    console.log("Form is validated! Submitting the form...");
    setSubmitting(false);
  }}
>
  {() => (
    <Form>
      <div className="form-group">
        <label htmlFor="email">Email</label>
        <Field
          type="email"
          name="email"
          className="form-control"
        />
      </div>
      <div className="form-group">
        <label htmlFor="password">Password</label>
        <Field
          type="password"
          name="password"
          className="form-control"
        />
      </div>
    </Form>
  )}
</Formik>

У Formik есть собственный метод handleChange, который можно использовать для обновления состояния при пользовательском вводе данных в поля формы. Таким образом отпадает необходимость реализовывать собственный метод handleChange. В примере ниже метод handleChange обновляет значения поля email в состоянии формы на основании атрибута name, если в этом поле будут изменения:

const SignupForm = () => {
  const formik = useFormik({
    initialValues: {
      email: "",
    },
    onSubmit: (values) => {
      console.log(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>
  );
};

Метод handleChange используется с input-элементами, а компонент <Field> самостоятельно обновляет значения без необходимости реализации метода handleChange.

Читайте также: Маршрутизация в React Router: как она работает и почему ее выбирают разработчики

Валидация и сообщения об ошибках в Formik

Валидация очень важна при создании форм. Если формы правильно не обрабатываются, это может привести к большому количеству ошибок. Формы должны сообщать пользователям, какие поля являются обязательными и какие типы значений разрешены в определенных полях. Это также помогает дать пользователям четкое представление о том, что не так с их вводом.

Валидация в Formik выполняется автоматически во время определенных событий, такие как ввод данных пользователем, изменение фокуса и отправка. При этом Formik поддерживает валидацию как на уровне формы, так и на уровне поля. Все, что нужно сделать, это передать функцию проверки в компонент <Formik /> или <Field /> через проп validate:

// Synchronous validation
 const validate = (values, props) => {
   const errors = {};

   if (!values.email) {
     errors.email = 'Required';
   } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
     errors.email = 'Invalid email address';
   }

   //...

   return errors;
 };

Как показать сообщения об ошибках в Formik

Formik предоставляет компонент <ErrorMessage /> для автоматического отображения сообщений об ошибках для компонента <Field /> с соответствующим именем (name).

<ErrorMessage /> через свойство component позволяет указать, какой HTML-тег будет отображаться:

<Field
  type="email"
  name="email"
  className={`form-control ${
    touched.email && errors.email ? "is-invalid" : ""
  }`}
/>
<ErrorMessage
  component="div"
  name="email"
  className="invalid-feedback"
/>

Валидация с помощью Yup

Как мы говорили выше, Formik поддерживает валидацию как на уровне формы, так и на уровне поля, и за разработчиком остается право написать свою реализацию валидации. Однако можно пойти дальше и воспользоваться возможностью связать Formik c Yup.

Yup — это библиотека для валидации объектов JS. Она позволяет описать схему валидации объекта, где для каждого свойства объекта устанавливается ряд ограничений, и далее на этом объекте вызывается метод валидации validate.

Formik предоставляет поддержку схем валидации validationSchema в Yup — она автоматически преобразует ошибки валидации из Yup в объект, ключи которого соответствуют значениям полей формы.

Читайте также: Как деплоить приложение на Railway. Гайд для фронтендеров и бэкендеров

Для того, чтобы добавить Yup в проект, нужно установить его из npm:

npm install yup --save
import React from 'react';
import { Formik, Form, Field } from 'formik';
import * as Yup from 'yup';

const SignupSchema = Yup.object().shape({
  firstName: Yup.string()
    .min(2, 'Минимум 2 буквы')
    .max(50, 'Максимум 50 букв')
    .required('Обязательное поле'),
  lastName: Yup.string()
    .min(2, 'Минимум 2 буквы')
    .max(50, 'Максимум 50 букв')
    .required('Обязательное поле'),
  email: Yup.string().email('Неверный email').required('Обязательное поле'),
});

export const ValidationSchemaExample = () => (
  <div>
    <h1>Signup</h1>
    <Formik
      initialValues={{
        firstName: '',
        lastName: '',
        email: '',
      }}
      validationSchema={SignupSchema}
      onSubmit={ (values) => {
        console.log(values);
      }}
    >
      {({ errors, touched }) => (
        <Form>
          <Field name="firstName" />
          {errors.firstName && touched.firstName ? (
            <div>{errors.firstName}</div>
          ) : null}
          <Field name="lastName" />
          {errors.lastName && touched.lastName ? (
            <div>{errors.lastName}</div>
          ) : null}
          <Field name="email" type="email" />
          {errors.email && touched.email ? <div>{errors.email}</div> : null}
          <button type="submit">Submit</button>
        </Form>
      )}
    </Formik>
  </div>
);

Отправка формы в Formik

Formik использует функцию onSubmit для обработки данных формы всякий раз, когда нажимается кнопка отправки. Валидация запускается автоматически, но отправка формы отменится, если есть какие-либо ошибки.

В примере ниже функция onSubmit вызывается при отправке формы и использует функцию setSubmitting для обновления состояния компонента Formik в процессе отправки.

<Formik
   initialValues={{ username: "", email: "", password: "" }}
   // . . .
   onSubmit={(values, { setSubmitting }) => {
     setTimeout(() => {
       console.log(JSON.stringify(values, null, 2));
       setSubmitting(false);
     }, 400);
   }}
>

Заключение

Formik является одной из тех библиотек с открытым исходным кодом, которая необходима, если вы пишете много форм в своем приложении на React. Она делает процесс создания формы относительно быстрым и интуитивно понятным, особенно при создании сложных форм.

В этой статье мы рассмотрели основные возможности библиотеки. Если вы хотите узнать больше о Formik, то дополнительную информацию можно найти в официальной документации библиотеки.

Станьте профессиональным фронтенд-разработчиком с нуля за 10 месяцев На Хекслете есть профессия «Фронтенд-разработчик». Пройдите ее, чтобы изучить один из самых известных языков программирования, освоить популярные фреймворки и создать большое портфолио с проектами на GitHub.

Стать JS-разработчиком

Аватар пользователя Olga Pejenkova
Olga Pejenkova 20 апреля 2023
16
Похожие статьи
Рекомендуемые программы
профессия
Верстка на HTML5 и CSS3, Программирование на JavaScript в браузере, разработка клиентских приложений используя React
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на Python, Разработка веб-приложений и сервисов используя Django, проектирование и реализация REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
Тестирование веб-приложений, чек-листы и тест-кейсы, этапы тестирования, DevTools, Postman, SQL, Git, HTTP/HTTPS, API
4 месяца
с нуля
Старт 26 декабря
профессия
Программирование на Java, Разработка веб-приложений и микросервисов используя Spring Boot, проектирование REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
новый
Google таблицы, SQL, Python, Superset, Tableau, Pandas, визуализация данных, Anaconda, Jupyter Notebook, A/B-тесты, ROI
9 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на PHP, Разработка веб-приложений и сервисов используя Laravel, проектирование и реализация REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на Ruby, Разработка веб-приложений и сервисов используя Rails, проектирование и реализация REST API
5 месяцев
c опытом
Старт 26 декабря
профессия
Программирование на JavaScript в браузере и на сервере (Node.js), разработка бекендов на Fastify и фронтенда на React
16 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на JavaScript, разработка веб-приложений, bff и сервисов используя Fastify, проектирование REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
новый
Git, JavaScript, Playwright, бэкенд-тесты, юнит-тесты, API-тесты, UI-тесты, Github Actions, HTTP/HTTPS, API, Docker, SQL
8 месяцев
c опытом
Старт 26 декабря