JavaRush /Курсы /Модуль 3: React /Асинхронная валидация с использованием Yup

Асинхронная валидация с использованием Yup

Модуль 3: React
5 уровень , 6 лекция
Открыта

Почему нужна асинхронная валидация?

Асинхронная валидация используется там, где данные формы нужно проверять на стороне сервера или нужно выполнить длительную проверку (например, убедиться, что email или имя пользователя уникальны). Давайте разберём, как это работает, зачем это нужно и как всё это настроить с помощью Yup и Formik.

Представьте ситуацию: вы регистрируете пользователя на сайте. Часто бывает так, что email или имя пользователя уже занято, и эту информацию нужно проверить на сервере. Очевидно, что одной только клиентской валидацией тут не обойтись. Для таких случаев нам и пригодится асинхронная валидация.

Основные преимущества асинхронной валидации:

  1. Проверка данных на уникальность (например, email, username).
  2. Комбинация клиентской и серверной валидации для более строгого контроля данных.
  3. Возможность выполнять более сложные или долгие проверки на стороне сервера, которые нецелесообразно выносить в код клиента.

Как работает асинхронная валидация в Yup?

Yup поддерживает асинхронные проверки с использованием Promise. Это позволяет включать в схему проверки данные, которые нужно валидировать на стороне сервера или через сторонние API.

Yup предоставляет метод test, который можно использовать для создания кастомных (пользовательских) валидаторов, включая асинхронные функции. Вот его базовый синтаксис:

Yup.string().test(
  'unique', // уникальное имя проверки
  'Такой email уже используется', // сообщение об ошибке
  async (value) => {
    // Ваша асинхронная логика проверки
    const isUnique = await проверкаНаСервере(value);
    return isUnique; // true, если значение валидное, иначе false
  }
);

Теперь давайте рассмотрим более реалистичный пример.

Пример асинхронной валидации email

Рассмотрим форму регистрации пользователя, в которой необходимо проверить, что email не занят другим пользователем. Для этого мы создадим функцию checkEmailExists, которая будет эмулировать проверку на сервере.

1. Создаём асинхронную функцию проверки email

Для эмуляции серверной проверки создадим небольшую функцию, которая возвращает Promise с результатом:

const checkEmailExists = async (email: string): Promise<boolean> => {
  // Эмуляция API-запроса
  const existingEmails = ['test@example.com', 'admin@example.com'];
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(existingEmails.includes(email)); // true, если email уже существует
    }, 1000); // Эмуляция задержки в 1 секунду
  });
};

2. Создаём схему валидации с Yup

Теперь включим асинхронную валидацию в схему Yup:

import * as Yup from 'yup';

const validationSchema = Yup.object({
  email: Yup.string()
    .email('Неверный формат email')
    .required('Email обязателен')
    .test(
      'unique-email', // уникальное имя проверки
      'Этот email уже занят', // сообщение об ошибке
      async (value) => {
        if (!value) return true; // Пропускаем проверку, если поле пустое
        const emailExists = await checkEmailExists(value);
        return !emailExists; // true, если email уникален
      }
    ),
});

Что здесь происходит:

  • Поле email сначала проверяется на формат (метод email и обязательность required.
  • Затем используется test для кастомной проверки. Функция checkEmailExists возвращает true, если email уже существует, и в таком случае валидация завершится с ошибкой.

3. Создаём форму с использованием Formik

Теперь добавим эту схему в нашу форму с помощью Formik:

import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';

const RegistrationForm: React.FC = () => {
  const initialValues = { email: '' };

  const handleSubmit = (values: { email: string }) => {
    console.log('Форма отправлена:', values);
  };

  const validationSchema = Yup.object({
    email: Yup.string()
      .email('Неверный формат email')
      .required('Email обязателен')
      .test(
        'unique-email',
        'Этот email уже занят',
        async (value) => {
          if (!value) return true;
          const emailExists = await checkEmailExists(value);
          return !emailExists;
        }
      ),
  });

  return (
    <Formik
      initialValues={initialValues}
      validationSchema={validationSchema}
      onSubmit={handleSubmit}
    >
      {({ isSubmitting }) => (
        <Form>
          <div>
            <label htmlFor="email">Email:</label>
            <Field id="email" name="email" type="email" />
            <ErrorMessage name="email" component="div" className="error" />
          </div>
          <button type="submit" disabled={isSubmitting}>
            {isSubmitting ? 'Проверка...' : 'Отправить'}
          </button>
        </Form>
      )}
    </Formik>
  );
};
  • Поле email подключено к схеме валидации.
  • При вводе пользовательского email будет происходить асинхронная проверка.

Советы по улучшению UX

  1. Индикатор загрузки для асинхронной проверки: если вы хотите визуально обозначить, что происходит проверка, можно использовать состояние isSubmitting или добавить локальное состояние для управления индикатором.

  2. Дебаунс вводимых данных: чтобы избежать избыточного количества запросов, можно использовать "дебаунсинг" (задержка между вводом текста). Например, с помощью библиотеки lodash.debounce.

  3. Кэш результата проверки: если пользователь вводит один и тот же email, можно сохранить результат проверки в локальном состоянии или кэше, чтобы не отправлять повторные запросы.

Типичные ошибки

Иногда разрабатывая асинхронную валидацию, можно столкнуться с непростыми ситуациями. Например, если пользователь вводит данные слишком быстро, валидация может быть отменена или не выполнена корректно. Вы можете использовать библиотеку вроде AbortController для отмены предыдущего запроса. Ещё одна проблема — это игнорирование ошибки или её неправильная обработка. Всегда проверяйте, что ваш try/catch блок корректно установлен внутри асинхронного метода.

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

1
Задача
Модуль 3: React, 5 уровень, 6 лекция
Недоступна
Создание асинхронной проверки email
Создание асинхронной проверки email
1
Задача
Модуль 3: React, 5 уровень, 6 лекция
Недоступна
Интеграция асинхронной валидации в Yup
Интеграция асинхронной валидации в Yup
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ