Валидация полей ввода

В библиотеке MUI (Material-UI) валидация форм строится вокруг компонентов ввода, таких как TextField, Select, Checkbox и их комбинаций с формами. Ключевой подход заключается в управлении состоянием формы через локальный стейт или библиотеки для управления формами, например, react-hook-form или Formik.

TextField и встроенные свойства

Компонент TextField поддерживает несколько встроенных свойств, важных для валидации:

  • required — отмечает поле как обязательное.
  • error — принимает булево значение; при true поле отображается с красной обводкой, сигнализируя об ошибке.
  • helperText — позволяет выводить сообщение об ошибке или подсказку.

Пример базовой валидации:

<TextField
  label="Email"
  value={email}
  onCha nge={(e) => setEmail(e.target.value)}
  required
  error={!email.includes('@')}
  helperText={!email.includes('@') ? 'Введите корректный email' : ''}
/>

В этом примере проверка корректности email выполняется напрямую в компоненте. error реагирует на условие, а helperText информирует пользователя.

Управление формами с react-hook-form

Для сложных форм с множеством полей удобнее использовать react-hook-form. Она интегрируется с MUI через обертку Controller.

Пример использования Controller:

import { useForm, Controller } from 'react-hook-form';
import TextField from '@mui/material/TextField';

const { control, handleSubmit, formState: { errors } } = useForm();

<Controller
  name="username"
  control={control}
  defaultValue=""
  rules={{ required: 'Имя пользователя обязательно', minLength: { value: 3, message: 'Минимум 3 символа' } }}
  render={({ field }) => (
    <TextField
      {...field}
      label="Имя пользователя"
      error={!!errors.username}
      helperText={errors.username ? errors.username.message : ''}
    />
  )}
/>

Здесь ключевые моменты:

  • rules определяет правила валидации, включая обязательность, минимальную длину, паттерны для регулярных выражений и кастомные функции.
  • errors позволяет отобразить конкретное сообщение об ошибке.
  • Controller связывает MUI-компонент с внутренней логикой формы.

Кастомные правила валидации

MUI не накладывает ограничений на то, какие проверки можно делать. Можно реализовать сложные сценарии:

rules={{
  validate: value => {
    if (value.length < 8) return 'Пароль слишком короткий';
    if (!/[A-Z]/.test(value)) return 'Пароль должен содержать хотя бы одну заглавную букву';
    return true;
  }
}}

Функция validate возвращает строку с ошибкой, если правило не выполнено, или true, если поле валидно.

Валидация select, checkbox и радио

MUI компоненты Select, Checkbox и RadioGroup также поддерживают валидацию через Controller:

<Controller
  name="gender"
  control={control}
  rules={{ required: 'Выберите пол' }}
  render={({ field }) => (
    <Select {...field} label="Пол" error={!!errors.gender}>
      <MenuItem value="male">Мужской</MenuItem>
      <MenuItem value="female">Женский</MenuItem>
    </Select>
  )}
/>
<FormHelperText error={!!errors.gender}>
  {errors.gender?.message}
</FormHelperText>

Особенности:

  • Для Select и RadioGroup сообщение об ошибке выводится отдельно через FormHelperText.
  • Checkbox можно валидировать, проверяя значение checked.

Асинхронная валидация

Иногда требуется проверка на сервере, например, уникальность логина. MUI не ограничивает интеграцию с асинхронной логикой:

rules={{
  validate: async value => {
    const isTaken = await checkUsername(value);
    return isTaken ? 'Имя пользователя занято' : true;
  }
}}

Асинхронная функция возвращает строку ошибки при невалидном значении или true, если проверка успешна.

Динамическая валидация и управление состоянием

Для комплексных форм с несколькими шагами или зависимыми полями можно комбинировать локальный стейт и react-hook-form:

  • Использовать watch для отслеживания изменений в определённых полях.
  • Изменять правила валидации в зависимости от состояния других полей.

Пример: если отмечен чекбокс «Показать дополнительные поля», можно добавить обязательность для скрытых полей:

const showExtra = watch('showExtra');
<Controller
  name="extraField"
  control={control}
  rules={{ required: showExtra ? 'Поле обязательно' : false }}
  render={({ field }) => <TextField {...field} label="Дополнительно" error={!!errors.extraField} helperText={errors.extraField?.message} />}
/>

Стратегии UX при валидации

  • Мгновенная проверка (onChange) — ошибки отображаются сразу при вводе, повышая интерактивность.
  • Проверка при отправке (onSubmit) — снижает визуальный шум для сложных форм.
  • Комбинированный подход — отображать базовые ошибки сразу, а более сложные проверки при отправке.

Итоговые принципы

  • Использовать TextField, Select, Checkbox, RadioGroup с error и helperText для отображения ошибок.
  • Для сложных форм применять react-hook-form или Formik с Controller для интеграции MUI-компонентов.
  • Правила валидации могут быть синхронными и асинхронными, простыми и комплексными.
  • Асинхронная проверка, динамические правила и зависимые поля позволяют строить гибкую и интерактивную форму без ограничений MUI.
  • Визуальная обратная связь (error, helperText) всегда должна быть синхронизирована с состоянием формы.

Эти подходы позволяют создавать формы с надёжной валидацией, соответствующей современным требованиям UX и стандартам Material Design.