Переиспользование логики

React Aria предоставляет набор хуков, предназначенных для обеспечения доступности (accessibility) компонентов интерфейса. Одним из ключевых преимуществ этих хуков является возможность переиспользования логики, что позволяет создавать сложные компоненты без повторного внедрения стандартных паттернов доступности. Основной принцип заключается в том, что хуки возвращают набор props и state, которые можно напрямую передавать элементам JSX.


Основные хуки для управления состоянием

React Aria делит логику компонентов на две части: ARIA-логика и управление состоянием. Для состояния чаще всего используются хуки из react-stately, но комбинация их с хуками из react-aria обеспечивает полную интеграцию.

Примеры ключевых хуков:

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

Все эти хуки не рендерят JSX, а возвращают набор props, которые затем могут быть распределены на любые компоненты. Это позволяет переиспользовать один и тот же хук в разных UI-библиотеках или кастомных компонентах, сохраняя при этом корректное поведение с точки зрения доступности.


Переиспользование логики с useButton

Рассмотрим пример с кнопкой:

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

function AccessibleButton(props) {
  const ref = useRef();
  const {buttonProps} = useButton(props, ref);

  return (
    <button {...buttonProps} ref={ref}>
      {props.children}
    </button>
  );
}
  • useButton автоматически обрабатывает события onClick, onKeyDown, а также добавляет корректные ARIA-атрибуты.
  • Хук отделяет логику от представления, что позволяет использовать её с любым HTML-элементом или кастомным компонентом.
  • При необходимости можно расширять функциональность, передавая дополнительные props или комбинируя с другими хуками.

Паттерн переиспользования: комбинирование хуков

React Aria позволяет создавать составные компоненты, комбинируя несколько хуков. Например, меню с кнопкой открытия:

import {useMenuTrigger} from '@react-aria/menu';
import {useButton} from '@react-aria/button';
import {useMenu} from '@react-aria/menu';
import {useState, useRef} from 'react';

function DropdownMenu({items}) {
  const [isOpen, setOpen] = useState(false);
  const buttonRef = useRef();
  const menuRef = useRef();

  const {menuTriggerProps, menuProps} = useMenuTrigger({type: 'menu'}, {isOpen, setOpen}, buttonRef);
  const {buttonProps} = useButton(menuTriggerProps, buttonRef);

  return (
    <>
      <button {...buttonProps} ref={buttonRef}>Открыть меню</button>
      {isOpen && (
        <ul {...menuProps} ref={menuRef}>
          {items.map(item => (
            <li key={item.key}>{item.name}</li>
          ))}
        </ul>
      )}
    </>
  );
}

Преимущества такого подхода:

  • Логика меню и кнопки полностью переиспользуется без дублирования.
  • Состояние открытия (isOpen) можно контролировать извне или оставлять внутренним.
  • ARIA-атрибуты и события клавиатуры обрабатываются автоматически.

Создание кастомных хуков для повторного использования

Для упрощения разработки крупных приложений часто создаются обертки над React Aria хуками:

import {useCheckbox} from '@react-aria/checkbox';
import {useState, useRef} from 'react';

export function useAccessibleCheckbox(initialValue = false) {
  const [checked, setChecked] = useState(initialValue);
  const ref = useRef();

  const {inputProps} = useCheckbox({isSelected: checked, onChange: setChecked}, ref);

  return {inputProps, checked, setChecked, ref};
}

Такой хук позволяет использовать одинаковую ARIA-логику во множестве компонентов, не повторяя каждый раз конфигурацию useCheckbox.


Параметры для гибкости

Переиспользуемые хуки обычно поддерживают следующие параметры для кастомизации:

  • isDisabled – блокировка компонента.
  • isReadOnly – запрет на изменение значения.
  • validationState – состояние валидации (valid, invalid).
  • onChange – callback для обработки изменений состояния.

Эти параметры обеспечивают возможность масштабирования компонентов и применения их в разных контекстах без изменения исходной логики.


Принципы организации кода

  1. Отделение логики от UI – хуки предоставляют только состояние и props.
  2. Создание переиспользуемых оберток – упрощает повторное использование компонентов с одинаковой функциональностью.
  3. Композиция хуков – объединение нескольких хуков для сложных интерфейсов, таких как меню, модальные окна, переключатели.
  4. Передача ref и props – обеспечивает интеграцию с любыми элементами, включая кастомные компоненты.

Примеры сложного переиспользования

  • Список с выбором элементов – комбинация useListBox и useOption для создания доступного списка с клавиатурной навигацией.
  • Таблица с сортировкой и фильтрацией – объединение useTable, useTableColumnHeader и useCheckbox для управления выделением и сортировкой.
  • Модальные окна – использование useOverlay и useModal для корректного управления фокусом и событиями клавиатуры.

Вывод

React Aria превращает стандартные UI-паттерны в переиспользуемую и масштабируемую логику, отделяя ARIA-обработку от представления. Любой компонент, построенный с хуками React Aria, может быть универсальным, доступным и легко интегрируемым в различные проекты, что делает библиотеку идеальной для построения крупных интерфейсов с повторно используемой логикой.