Работа с React Hook Form

Библиотека React Aria предоставляет готовые хуки и утилиты для управления доступностью и поведением интерфейсных компонентов, а React Hook Form облегчает работу с формами в React, обеспечивая простое управление состоянием, валидацией и производительностью. Совмещение этих библиотек позволяет создавать полностью доступные формы с минимальным количеством повторяющегося кода.


Подключение и установка зависимостей

Для работы необходимо установить обе библиотеки:

npm install @react-aria/aria @react-aria/button @react-aria/checkbox react-hook-form

Основные пакеты React Aria, которые будут использоваться при работе с формами:

  • useCheckbox – управление состоянием и доступностью чекбоксов.
  • useButton – корректное поведение кнопок с поддержкой клавиатурной навигации.
  • useTextField – обработка текстовых полей с учетом ARIA-атрибутов.

React Hook Form предоставляет:

  • useForm – основной хук для управления состоянием формы.
  • Controller – компонент для интеграции контролируемых компонентов, таких как те, что предоставлены React Aria.

Использование Controller для компонентов React Aria

React Hook Form по умолчанию работает с неконтролируемыми элементами, но компоненты React Aria часто требуют контролируемого состояния. Для интеграции используется Controller:

import { useForm, Controller } from "react-hook-form";
import { useCheckbox } from "@react-aria/checkbox";

function AccessibleCheckbox({ label, control, name }) {
  return (
    <Controller
      control={control}
      name={name}
      render={({ field }) => {
        let { inputProps } = useCheckbox(field);
        return (
          <label>
            <input {...inputProps} />
            {label}
          </label>
        );
      }}
    />
  );
}

Ключевые моменты:

  • useCheckbox возвращает inputProps, которые обеспечивают правильную доступность (ARIA-атрибуты, обработка клавиатуры).
  • Controller передает field объект, содержащий value, onChange и onBlur, что позволяет синхронизировать состояние с React Hook Form.

Работа с текстовыми полями

Для текстовых полей используется useTextField:

import { useTextField } from "@react-aria/textfield";

function AccessibleInput({ label, control, name }) {
  return (
    <Controller
      control={control}
      name={name}
      render={({ field }) => {
        let { inputProps, labelProps } = useTextField(field);
        return (
          <div>
            <label {...labelProps}>{label}</label>
            <input {...inputProps} />
          </div>
        );
      }}
    />
  );
}

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

  • labelProps гарантируют, что метка корректно связана с полем.
  • inputProps включают ARIA-атрибуты, обработчики фокуса и состояния ошибки, если они переданы.

Кнопки с поддержкой доступности

useButton позволяет добавить кнопке полную поддержку клавиатуры и ARIA:

import { useButton } from "@react-aria/button";

function SubmitButton({ children, onPress }) {
  let ref = React.useRef();
  let { buttonProps } = useButton({ onPress }, ref);
  
  return (
    <button {...buttonProps} ref={ref}>
      {children}
    </button>
  );
}

Использование с формой:

function Form() {
  const { handleSubmit } = useForm();
  
  const onSub mit = data => console.log(data);
  
  return (
    <form onSub mit={handleSubmit(onSubmit)}>
      <AccessibleInput name="username" label="Имя пользователя" control={control} />
      <AccessibleCheckbox name="agree" label="Согласие" control={control} />
      <SubmitButton>Отправить</SubmitButton>
    </form>
  );
}

Валидация и обработка ошибок

React Hook Form позволяет легко добавлять правила валидации, а React Aria помогает отображать ошибки с корректными ARIA-атрибутами:

<Controller
  control={control}
  name="email"
  rules={{ required: "Email обязателен", pattern: { value: /^\S+@\S+$/i, message: "Некорректный email" } }}
  render={({ field, fieldState }) => {
    let { inputProps, labelProps } = useTextField(field);
    return (
      <div>
        <label {...labelProps}>Email</label>
        <input {...inputProps} />
        {fieldState.error && <span role="alert">{fieldState.error.message}</span>}
      </div>
    );
  }}
/>

Принципы:

  • fieldState.error содержит сообщение об ошибке, которое автоматически обновляется при изменении значения.
  • Использование role="alert" позволяет экранным читалкам уведомлять пользователя о ошибке.

Управление фокусом и интерактивностью

React Aria предоставляет хуки для управления фокусом (useFocusRing, useFocus) и взаимодействием с клавиатурой. Это особенно важно для форм с динамическими элементами:

import { useFocusRing } from "@react-aria/focus";

function FocusableInput({ label, control, name }) {
  return (
    <Controller
      control={control}
      name={name}
      render={({ field }) => {
        let { inputProps } = useTextField(field);
        let { isFocusVisible, focusProps } = useFocusRing();
        
        return (
          <div>
            <label>{label}</label>
            <input {...inputProps} {...focusProps} style={{ outline: isFocusVisible ? "2px solid blue" : "none" }} />
          </div>
        );
      }}
    />
  );
}

Эффекты:

  • Обеспечивает визуальную индикацию фокуса для клавиатурных пользователей.
  • Поддержка совместной работы с React Hook Form сохраняет контролируемое состояние.

Советы по производительности

  1. Использование Controller только там, где это необходимо. Неконтролируемые поля через register более производительны.
  2. Избегание лишних ререндеров. React Aria хуки минимизируют ререндеры за счет использования useState внутри компонентов.
  3. Группировка логики в отдельные компоненты. Это упрощает повторное использование и поддерживает чистоту кода.

Итоговое применение

Комбинация React Aria и React Hook Form позволяет создавать формы с:

  • Полной поддержкой ARIA и доступностью
  • Легкой интеграцией валидации и ошибок
  • Контролируемым состоянием и управлением фокусом
  • Минимальным повторением кода и высокой производительностью

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