JavaRush /Курсы /Модуль 3: React /Типизация правил валидации и обработка ошибок

Типизация правил валидации и обработка ошибок

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

Основы Yup и его типов

Официальная документация по Yup — это чудесный источник вдохновения. Но давайте упростим всё прямо сейчас.

Библиотека Yup предоставляет нам возможность валидировать данные через создание схемы. Например:

import * as Yup from "yup";

// Простая схема валидации
const loginValidationSchema = Yup.object({
  email: Yup.string().email("Неверный формат email").required("Email обязателен"),
  password: Yup.string()
    .min(6, "Пароль должен содержать минимум 6 символов")
    .required("Пароль обязателен"),
});

Здесь мы проверяем два поля: email и password. Валидация происходит на уровне схемы, а Yup автоматически выбрасывает сообщения об ошибках, если правила нарушены.

Но что, если мы хотим добавить строгую типизацию?

Типизация Yup-схемы с TypeScript

Чтобы типизировать данные нашей формы и использовать их позже (например, при обработке ошибок), нужно создать интерфейс, представляющий структуру данных нашей формы.

// Описание интерфейса данных формы
interface LoginFormValues {
  email: string;
  password: string;
}

// Присваиваем интерфейс схеме валидации
const loginValidationSchema: Yup.SchemaOf<LoginFormValues> = Yup.object({
  email: Yup.string().email("Неверный формат email").required("Email обязателен"),
  password: Yup.string()
    .min(6, "Пароль должен содержать минимум 6 символов")
    .required("Пароль обязателен"),
});

Обратите внимание, как мы используем Yup.SchemaOf<LoginFormValues> для строгой типизации схемы. Теперь, если вы попытаетесь добавить несуществующий ключ, TypeScript вернёт вам ошибку ещё до выполнения кода. А это означает меньше багов и больше счастья.

Создание сложных правил валидации

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

interface RegisterFormValues {
  email: string;
  password: string;
  confirmPassword: string;
}

const registerValidationSchema: Yup.SchemaOf<RegisterFormValues> = Yup.object({
  email: Yup.string().email("Неверный формат email").required("Email обязателен"),
  password: Yup.string()
    .min(6, "Пароль должен содержать минимум 6 символов")
    .required("Пароль обязателен"),
  confirmPassword: Yup.string()
    .oneOf([Yup.ref("password")], "Пароли должны совпадать")
    .required("Подтвердите пароль"),
});

Обратите внимание на метод Yup.ref("password"). Он позволяет ссылаться на значение другого поля, чтобы сравнить данные. В данном случае мы проверяем, чтобы confirmPassword соответствовал введённому password.

Обработка ошибок с помощью Formik и Yup

Когда пользователь вводит данные, ошибки валидации могут сделать жизнь проще, а могут вызвать антипатию к вашему приложению. Мы же хотим, чтобы наши пользователи были в восторге! Для этого нужно показать внятные ошибки. Formik делает это легко:

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

// Определяем интерфейс формы
interface LoginFormValues {
  email: string;
  password: string;
}

// Схема валидации
const loginValidationSchema: Yup.SchemaOf<LoginFormValues> = Yup.object({
  email: Yup.string().email("Неверный формат email").required("Email обязателен"),
  password: Yup.string()
    .min(6, "Пароль должен содержать минимум 6 символов")
    .required("Пароль обязателен"),
});

const LoginForm = () => {
  const initialValues: LoginFormValues = { email: "", password: "" };

  return (
    <Formik
            initialValues={initialValues}
            validationSchema={loginValidationSchema}
            onSubmit={(values) => {
        console.log("Данные формы:", values);
      }}
    >
      {({ isSubmitting }) => (
        <Form>
          <div>
            <label htmlFor="email">Email:</label>
            <Field name="email" type="email" />
            <ErrorMessage name="email" component="div" />
          </div>
          <div>
            <label htmlFor="password">Пароль:</label>
            <Field name="password" type="password" />
            <ErrorMessage name="password" component="div" />
          </div>
          <button type="submit" disabled={isSubmitting}>
            Войти
          </button>
        </Form>
      )}
      </Formik>
      );
};

export default LoginForm;

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

  1. <ErrorMessage />: Formik предоставляет компонент для отображения сообщений об ошибках. В приведённом примере ошибки показываются, если они существуют для поля.
  2. Типизация: мы точно знаем, что данные формы соответствуют интерфейсу LoginFormValues, и можем безопасно использовать их при отправке.
  3. Валидация в реальном времени: каждый раз, когда пользователь меняет данные, Yup проверяет их, а Formik автоматически обновляет ошибки.

Отображение пользовательских сообщений об ошибках

Вы можете настроить отображение сообщений об ошибках, чтобы сделать их более дружелюбными или заметными. Например:

<ErrorMessage
  name="email"
  render={(msg) => <div style={{ color: "red" }}>{msg}</div>}
/>

Или даже заменить стандартные сообщения на эмодзи, чтобы разрядить атмосферу:

<ErrorMessage
  name="password"
  render={(msg) => (
    <div style={{ color: "orange" }}>⚠️ {msg}</div>
  )}
/>

Типичные ошибки и как их избежать

Один из самых распространённых ошибок — это несоответствие интерфейса данных и схемы валидации. Например, если вы добавите новое поле в интерфейс, но забудете обновить схему, TypeScript предупредит вас.

Ещё одной проблемой может стать отсутствие обработки ошибок. Если сообщения не отображаются для пользователя, вполне возможно, что ошибка в имени поля или компоненте <ErrorMessage />.

Реальное применение знаний

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

На собеседованиях синьоров особенно любят спрашивать про типизацию сложных форм. Упомяните Yup и TypeScript, и вы получите бонусные очки за техническую эрудицию.

Не забывайте комбинировать типы, схемы и обработку ошибок для создания безупречных приложений, которые полюбят пользователи (и их тестировщики). Успехов в реализации будущих форм!

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