React Aria предоставляет набор хуков, которые реализуют доступность интерфейсов (accessibility) на уровне компонентов, оставляя контроль над визуальной частью разработчику. Ключевая цель переиспользуемых паттернов — создание универсальных, модульных и доступных компонентов, которые можно использовать в разных частях приложения без дублирования кода.
Большинство паттернов React Aria строятся вокруг хуков, которые разделяют логику и представление:
Паттерн переиспользования: вынесение состояния и обработчиков в отдельный хук, а рендер оставлять за конкретным компонентом.
function useCustomToggle(initialState = false) {
const [isOpen, setIsOpen] = React.useState(initialState);
const toggle = () => setIsOpen(prev => !prev);
return {
isOpen,
toggle,
props: {
'aria-expanded': isOpen,
onClick: toggle
}
};
}
Здесь useCustomToggle можно применять в кнопках, панелях
аккордеона или других интерактивных элементах.
React Aria позволяет комбинировать несколько хуков для построения комплексного компонента. Пример — комбинированный селект с доступностью:
import { useSelect, useButton } from '@react-aria/sel ect';
import { useState, useRef } fr om 'react';
function CustomSelect({ options }) {
const [selectedKey, setSelectedKey] = useState(null);
const ref = useRef();
const { labelProps, triggerProps, valueProps, menuProps } = useSelect(
{ selectedKey, onSelectionChange: setSelectedKey, items: options },
ref
);
const buttonProps = useButton(triggerProps, ref);
return (
<div>
<label {...labelProps}>Выберите элемент</label>
<button {...buttonProps} ref={ref}>
<span {...valueProps}>{selectedKey ?? "Выберите"}</span>
</button>
<ul {...menuProps}>
{options.map(item => (
<li key={item.key}>{item.name}</li>
))}
</ul>
</div>
);
}
Паттерн переиспользования: логика выбора и состояние
хука отделены от рендеринга списка и кнопки, что позволяет использовать
тот же useSelect для других визуальных реализаций
(дропдауны, кастомные панели).
Ключевой принцип — разделение визуального компонента и логики доступности. Например:
ToggleSwitch рендерит визуализацию переключателя.useToggle управляет состоянием и ARIA-атрибутами.function ToggleSwitch({ isOn, onChange }) {
const { inputProps } = useToggle({ isSelected: isOn, onChange });
return <input type="checkbox" {...inputProps} />;
}
Преимущества:
React Aria включает хуки для навигации и управления фокусом, которые можно переиспользовать в списках, таблицах и меню:
Для больших компонентов часто используется контекст, чтобы управлять состоянием дочерних элементов, не прокидывая пропсы через множество уровней:
const MenuContext = React.createContext();
function MenuProvider({ children }) {
const state = useMenuState(); // кастомный хук для состояния меню
return <MenuContext.Provider value={state}>{children}</MenuContext.Provider>;
}
function MenuItem({ item }) {
const state = React.useContext(MenuContext);
const { menuItemProps } = useMenuItem({ key: item.key }, state);
return <li {...menuItemProps}>{item.name}</li>;
}
Паттерн переиспользования: любой компонент внутри провайдера автоматически получает доступ к состоянию меню без дублирования логики.
В дополнение к хукам, React Aria предоставляет хелперы, которые часто переиспользуются:
mergeProps — объединяет несколько наборов пропсов,
чтобы не потерять события и ARIA-атрибуты.filterDOMProps — фильтрует допустимые HTML-атрибуты,
предотвращая ошибки при передаче неизвестных свойств.import { mergeProps } from '@react-aria/utils';
function CustomInput({ inputProps, additionalProps }) {
const props = mergeProps(inputProps, additionalProps);
return <input {...props} />;
}
mergeProps,
filterDOMProps) делают компоненты более
универсальными.Эти подходы образуют основу переиспользуемых паттернов в React Aria и позволяют строить крупные, доступные и модульные интерфейсы без дублирования кода.