Хуки для поведения

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

useButton

Хук useButton предназначен для управления поведением кнопки. Он обеспечивает корректную обработку событий клика, клавиатурных взаимодействий и атрибутов доступности.

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

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

function Button(props) {
  let ref = useRef();
  let { buttonProps } = useButton(props, ref);

  return <button {...buttonProps} ref={ref}>{props.children}</button>;
}

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

  • Автоматическая поддержка клавиш Enter и Space.
  • Установка атрибута aria-disabled при isDisabled.
  • Обработка onPress, onPressStart, onPressEnd для разных стадий взаимодействия.

useCheckbox

Хук useCheckbox управляет состоянием флажка (checkbox) с учётом доступности. Позволяет работать как с контролируемым, так и с неконтролируемым состоянием.

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

function Checkbox(props) {
  let ref = useRef();
  let [isSelected, setSelected] = useState(false);
  let { inputProps } = useCheckbox({ ...props, isSelected, onChange: setSelected }, ref);

  return <input {...inputProps} ref={ref} />;
}

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

  • Поддержка трёх состояний (checked, unchecked, mixed) через aria-checked.
  • Интеграция с родительскими элементами для составных компонентов (например, группы чекбоксов).
  • Управление фокусом и клавишами Space и Enter.

useFocus

Хук useFocus позволяет отслеживать и управлять состоянием фокуса. Особенно полезен для кастомных элементов, где стандартный <input> не используется.

import { useFocus } from '@react-aria/focus';
import { useRef } from 'react';

function FocusableDiv() {
  let ref = useRef();
  let { focusProps, isFocused } = useFocus();

  return (
    <div {...focusProps} ref={ref} style={{ outline: isFocused ? '2px solid blue' : 'none' }}>
      Нажми Tab, чтобы сфокусироваться
    </div>
  );
}

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

  • Возврат состояния isFocused для визуальных индикаторов.
  • Управление событиями onFocus и onBlur через объединение с пользовательскими обработчиками.
  • Поддержка вложенных и составных компонентов с делегированным фокусом.

useHover

Хук useHover контролирует поведение при наведении мыши и учитывает мобильные устройства, где наведение отсутствует.

import { useHover } from '@react-aria/interactions';
import { useRef } from 'react';

function HoverableDiv() {
  let ref = useRef();
  let { hoverProps, isHovered } = useHover({});

  return (
    <div {...hoverProps} ref={ref} style={{ background: isHovered ? 'lightgray' : 'white' }}>
      Наведи курсор сюда
    </div>
  );
}

Ключевые возможности:

  • Состояние isHovered для визуальных эффектов.
  • Игнорирование наведения на сенсорных устройствах.
  • Объединение с другими хуками взаимодействия без конфликтов событий.

useMenu и useMenuItem

Для создания доступных меню используются хуки useMenu и useMenuItem. useMenu управляет списком элементов, а useMenuItem — отдельным элементом меню.

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

import { useMenu, useMenuItem } from '@react-aria/menu';
import { useRef } from 'react';

function Menu({ items }) {
  let ref = useRef();
  let { menuProps } = useMenu({ items }, ref);

  return (
    <ul {...menuProps} ref={ref}>
      {items.map(item => <MenuItem key={item.key} item={item} />)}
    </ul>
  );
}

function MenuItem({ item }) {
  let ref = useRef();
  let { menuItemProps, isFocused, isSelected } = useMenuItem({ key: item.key }, ref);

  return (
    <li {...menuItemProps} ref={ref} style={{ background: isFocused ? 'lightblue' : 'white' }}>
      {item.name} {isSelected && '✔'}
    </li>
  );
}

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

  • Управление выделением и фокусом элементов.
  • Поддержка клавиатурной навигации стрелками и Home/End.
  • Атрибуты доступности: role="menu", role="menuitem", aria-selected.

useSlider

Хук useSlider реализует поведение ползунков с учётом доступности и сенсорных интерфейсов.

  • Управление диапазоном значений через min, max, step.
  • Поддержка перемещения ползунка клавишами и мышью.
  • Возврат sliderProps для контейнера и thumbProps для ручки ползунка.
import { useSlider } from '@react-aria/slider';
import { useRef, useState } from 'react';

function SliderComponent() {
  let ref = useRef();
  let [value, setValue] = useState(50);
  let { sliderProps, trackProps, thumbProps } = useSlider({ minValue: 0, maxValue: 100, value, onChange: setValue }, ref);

  return (
    <div {...sliderProps} ref={ref}>
      <div {...trackProps}>
        <div {...thumbProps} />
      </div>
      <span>{value}</span>
    </div>
  );
}

Интеграция нескольких хуков

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

let { focusProps, isFocused } = useFocus();
let { hoverProps, isHovered } = useHover();
let combinedProps = { ...focusProps, ...hoverProps };
  • Важно правильно объединять обработчики событий, чтобы избежать конфликтов.
  • Все хуки предоставляют готовые атрибуты и состояния для безопасного использования с ARIA.

Рекомендации по использованию хуков поведения

  • Разделять логику и визуализацию компонентов. Хуки поведения должны управлять состоянием, событиями и ARIA-атрибутами.
  • Использовать контролируемые состояния для согласованного взаимодействия между компонентами.
  • Проверять поддержку клавиатурной навигации и экранных читалок.
  • Комбинировать хуки через спред (...) и проверять корректность передачи ref.

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