Интеграция с React Router

React Aria предоставляет набор хуков для управления доступностью интерактивных компонентов, включая меню, вкладки и ссылки. В комбинации с React Router можно создавать маршрутизируемые элементы, сохраняя при этом корректное поведение для пользователей с особыми потребностями.

Хук useLink позволяет управлять поведением ссылок на уровне доступности, включая обработку клавиатуры, фокусировки и атрибутов ARIA. При интеграции с React Router важно использовать компонент Link или NavLink вместо стандартного <a>:

import {useLink} from '@react-aria/link';
import {Link} from 'react-router-dom';
import {useRef} from 'react';

function RouterLink({to, children}) {
  let ref = useRef();
  let {linkProps} = useLink({
    elementType: 'a',
    href: to
  });

  return (
    <Link {...linkProps} to={to} ref={ref}>
      {children}
    </Link>
  );
}

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

  • linkProps обеспечивает правильную поддержку клавиатурных навигаций (Enter, Space) и корректные ARIA-атрибуты.
  • Передача elementType: 'a' необходима для совместимости с React Aria.
  • Использование ref позволяет React Aria управлять фокусом и взаимодействиями.

Интеграция вкладок с маршрутизацией

Для реализации маршрутизируемых вкладок применяются хуки useTabList и useTab. Они позволяют синхронизировать текущий активный маршрут с выбранной вкладкой:

import {useTabList, useTab} from '@react-aria/tabs';
import {NavLink, useLocation} from 'react-router-dom';
import {useRef} from 'react';

function Tab({to, children}) {
  let ref = useRef();
  let {tabProps} = useTab({}, ref);

  return (
    <NavLink to={to} {...tabProps} ref={ref}>
      {children}
    </NavLink>
  );
}

function TabNavigation({tabs}) {
  let ref = useRef();
  let {tabListProps} = useTabList({}, ref);

  return (
    <div {...tabListProps} ref={ref}>
      {tabs.map(tab => (
        <Tab key={tab.to} to={tab.to}>
          {tab.label}
        </Tab>
      ))}
    </div>
  );
}

Особенности реализации:

  • useTabList обеспечивает корректную навигацию между вкладками с клавиатуры.
  • NavLink автоматически выставляет активный класс на текущую вкладку, синхронизируя UI с маршрутом.
  • Каждая вкладка получает tabProps от React Aria для поддержки ARIA-ролей и состояний.

Динамические маршруты и меню

Для динамических маршрутов с выпадающими меню применяются хуки useMenu и useMenuItem. При использовании React Router элементы меню могут выступать ссылками на отдельные маршруты:

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

function MenuItemLink({to, children}) {
  let ref = useRef();
  let {menuItemProps} = useMenuItem({key: to}, ref);

  return (
    <Link {...menuItemProps} to={to} ref={ref}>
      {children}
    </Link>
  );
}

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

  return (
    <ul {...menuProps} ref={ref}>
      {items.map(item => (
        <li key={item.to}>
          <MenuItemLink to={item.to}>{item.label}</MenuItemLink>
        </li>
      ))}
    </ul>
  );
}

Важные аспекты:

  • Каждый элемент меню получает menuItemProps, обеспечивающий правильное управление фокусом и обработку клавиатуры.
  • Использование React Router Link позволяет сохранять SPA-навигацию без перезагрузки страницы.
  • Поддержка ARIA-атрибутов гарантирует совместимость с экранными читалками.

Управление состоянием маршрутов

React Aria не управляет состоянием маршрута напрямую. Для синхронизации состояния компонентов (например, активной вкладки или выбранного меню) используется React Router useLocation:

import {useLocation} from 'react-router-dom';

function ActiveTab({tabs}) {
  let location = useLocation();
  return tabs.find(tab => tab.to === location.pathname);
}

Рекомендации:

  • Хранение активного маршрута через useLocation позволяет корректно обновлять ARIA-состояния (aria-selected).
  • Избегать дублирования состояния между React Aria и React Router — источник ошибок при управлении фокусом и активными элементами.

Поддержка клавиатурной навигации

React Aria автоматически обрабатывает клавиатурные события для ссылок, вкладок и элементов меню. Важно при интеграции с React Router:

  • Передавать ref на элементы DOM.
  • Использовать хук useLink, useTab, useMenuItem для управления фокусом.
  • Не перекрывать события клавиатуры собственными обработчиками, если они не нужны для маршрутизации.

Вывод

Сочетание React Aria и React Router позволяет строить полностью доступные маршрутизируемые интерфейсы, где ссылки, вкладки и меню корректно управляются клавиатурой и поддерживают ARIA-стандарты, при этом остаются частью SPA-навигации. Использование хуков useLink, useTab, useMenuItem совместно с React Router Link и NavLink обеспечивает плавную интеграцию и совместимость с современными требованиями доступности.