JavaRush /Курсы /Модуль 3: React /Отображение пользовательских сообщений об ошибках

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

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

Важность отображения сообщений об ошибках

Мы добрались до одной из самых любимых (и ненавидимых) тем фронтенд-разработчиков — отображение сообщений об ошибках в формах. Если бы у разработчиков был тотем, связанный с пользовательским опытом, то это были бы осмысленные и понятные сообщения об ошибках. Ведь от того, как вы их покажете, зависит не только UX, но и количество пользователей, которые не бросят вашу форму на полпути из-за недоумения или ярости.

Сегодня мы поговорим о том, как использовать библиотеки Formik и Yup для создания удобных и информативных сообщений об ошибках в формах. Давайте начнем с вопроса: почему мы вообще паримся с сообщениями об ошибках?

Представьте, что вы пришли в магазин, а консультант вместо помощи молча смотрит на вас, когда вы пытаетесь выбрать что-то. Без подсказок сложно понять, что делать дальше, верно? То же самое и с формами.

Что делает хорошее сообщение об ошибке:

  • Понятность. Пользователь должен сразу понять, что пошло не так и как это исправить.
  • Контекст. Сообщение должно быть привязано к конкретному полю (а не абстрактное «что-то пошло не так»).
  • Чёткое место. Сообщение должно отображаться рядом с полем, чтобы не заставлять пользователя искать его.
  • Мгновенная обратная связь. Если ошибка исправлена — сообщение исчезает сразу.

Пример неправильного UX:

Пользователь вводит данные, нажимает «Отправить», а вы выдаёте один и тот же баннер: «Ошибка! Попробуйте снова». Позиция «гуляй, Вася!» в разработке, верно?

Пример формы

Чтобы продемонстрировать отображение ошибок, создадим простую форму для регистрации. Она будет включать следующие поля:

  • Email. Должен быть валидным адресом.
  • Password. Минимум 6 символов.
  • Confirm Password. Должен совпадать с полем Password.

Начнем с базового шаблона:

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

// Схема валидации с Yup
const validationSchema = Yup.object({
  email: Yup.string()
    .email("Некорректный Email")
    .required("Поле Email обязательно"),
  password: Yup.string()
    .min(6, "Минимальная длина пароля — 6 символов")
    .required("Поле Пароль обязательно"),
  confirmPassword: Yup.string()
    .oneOf([Yup.ref("password")], "Пароли должны совпадать")
    .required("Поле Подтверждения пароля обязательно"),
});

const RegistrationForm: React.FC = () => {
  return (
    <Formik
      initialValues={{ email: "", password: "", confirmPassword: "" }}
      validationSchema={validationSchema}
      onSubmit={(values) => {
        console.log("Submitted values:", values);
      }}
    >
      {({ handleSubmit, isSubmitting }) => (
        <Form onSubmit={handleSubmit}>
          <div>
            <label>Email</label>
            <Field name="email" type="email" />
            <ErrorMessage name="email" component="div" className="error" />
          </div>
          <div>
            <label>Пароль</label>
            <Field name="password" type="password" />
            <ErrorMessage name="password" component="div" className="error" />
          </div>
          <div>
            <label>Подтвердите пароль</label>
            <Field name="confirmPassword" type="password" />
            <ErrorMessage
                    name="confirmPassword"
                    component="div"
                    className="error"
            />
          </div>
          <button type="submit" disabled={isSubmitting}>
            Отправить
          </button>
        </Form>
      )}
    </Formik>
    );
};

export default RegistrationForm;

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

  1. Мы используем Formik для управления состоянием формы.
  2. Схема валидации создается через Yup (параметры валидности и сообщения об ошибках настраиваются здесь).
  3. Компонент ErrorMessage отвечает за отображение ошибок. Он автоматически связывается с указанным Field через имя поля.

Кастомизация сообщений об ошибках

Конечно, ErrorMessage из коробки просто работает, но это скучно, и мы, как настоящие разработчики, любим кастомизацию. Давайте создадим более кастомный способ отображения ошибок:

const ErrorText: React.FC<{ message: string }> = ({ message }) => (
  <div style={{ color: "red", fontSize: "14px" }}>{message}</div>
);

Теперь используем это в нашей форме:

<ErrorMessage name="email">
  {(msg) => <ErrorText message={msg} />}
</ErrorMessage>

Этот подход позволяет нам использовать однотипный стиль для всех ошибок. И да, никто не запрещает добавлять сюда иконки, анимации и всё, что сделает ваш UX космическим.

Реальная обратная связь: подсветка полей с ошибками

Ошибки — это не только текст, который нужно отобразить, но и визуальная подсказка, например, подсветка полей с проблемами. Удобно, когда пользователь сразу видит, что не так.

<Field
  name="email"
  type="email"
  className={`input ${errors.email && touched.email ? "input-error" : ""}`}
/>

И добавим CSS:

.input-error {
  border: 1px solid red;
  background-color: #ffe5e5;
}

Теперь каждое поле с ошибкой будет выделяться красным.

Отображение ошибок на уровне формы

Иногда ошибки нужно показывать не только для конкретного поля, но и для всей формы целиком. Например, если пользователь не прошёл капчу или сервер вернул ошибку. Formik поддерживает это через status и специальное свойство setStatus.

<Formik
  initialValues={{ email: "", password: "", confirmPassword: "" }}
  validationSchema={validationSchema}
  onSubmit={(values, { setStatus }) => {
    // Симулируем ошибку от сервера
    if (values.email === "test@test.com") {
      setStatus("Этот Email уже зарегистрирован");
    } else {
      console.log("Submitted values:", values);
    }
  }}
>
  {({ handleSubmit, status }) => (
    <Form onSubmit={handleSubmit}>
      {status && <div className="form-error">{status}</div>}
      {/* Остальные поля формы */}
    </Form>
  )}
</Formik>

CSS для ошибки формы:

.form-error {
  color: red;
  font-size: 16px;
  margin-bottom: 10px;
}

Типичные ошибки при работе с сообщениями об ошибках

Когда вы работаете с формами, ошибки неизбежны, и я говорю не об ошибках в данных, а о наших — разработческих. Вот самые частые проблемы:

  1. Вы забыли указать name для Field или ErrorMessage. Formik не сможет связать ошибки с полями, и ничего не будет отображаться.
  2. Использование if-else внутри схем валидации Yup может стать громоздким. Лучше разбивать правила на отдельные функции/методы.
  3. Игнорирование UX-подходов — например, не убирать сообщение об ошибке, когда пользователь всё исправил.

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

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