Хук useToggleButton из библиотеки React Aria
предназначен для создания доступных компонентов-переключателей. Он
обеспечивает корректное управление состоянием, соответствие стандартам
ARIA и удобство интеграции с пользовательскими интерфейсами. Основная
задача хука — предоставить все необходимые свойства и обработчики
событий для <button> или других элементов,
выполняющих роль переключателя.
Для работы с useToggleButton необходимо импортировать
хук и useToggleState для управления состоянием:
import { useToggleButton } from '@react-aria/button';
import { useToggleState } from '@react-stately/toggle';
Пример базового переключателя:
function ToggleExample() {
let state = useToggleState({ defaultSelected: false });
let ref = React.useRef();
let { buttonProps, isPressed } = useToggleButton({ isSelected: state.isSelected, onChange: state.toggle }, ref);
return (
<button {...buttonProps} ref={ref}>
{isPressed ? 'Включено' : 'Выключено'}
</button>
);
}
Ключевые моменты:
useToggleState управляет внутренним состоянием
компонента (isSelected).useToggleButton добавляет корректные ARIA-атрибуты
(aria-pressed) и обработчики событий.buttonProps содержит все необходимые свойства для
элемента <button>.isPressed позволяет визуально изменять контент кнопки в
зависимости от состояния.buttonPropsbuttonProps включает:
aria-pressed — отражает текущее
состояние переключателя (true или false).onPress — универсальный обработчик
кликов и нажатий клавиш.id и ref — обеспечивают
корректную привязку к DOM и поддержку фокуса.disabled — позволяет блокировать
кнопку.Использование buttonProps гарантирует соответствие
стандартам доступности без необходимости вручную прописывать атрибуты
ARIA.
useToggleState предоставляет следующие параметры:
let state = useToggleState({
defaultSelected: false, // начальное состояние
isSelected: undefined, // управляемое состояние
onChange: (selected) => console.log(selected) // колбэк при изменении
});
Особенности:
defaultSelected задаёт начальное состояние для
неуправляемого компонента.isSelected позволяет полностью контролировать состояние
снаружи.onChange вызывается при каждом изменении состояния, что
удобно для синхронизации с глобальным состоянием или API.useToggleButton автоматически обрабатывает клавиатурные
события:
ref, что обеспечивает корректную
навигацию с клавиатуры.Эта автоматизация избавляет от необходимости вручную писать
обработчики onKeyDown и onFocus.
useToggleButton можно использовать не только с
<button>, но и с другими элементами, выполняющими
роль переключателя:
function CustomToggle() {
let state = useToggleState({ defaultSelected: true });
let ref = React.useRef();
let { buttonProps } = useToggleButton({ isSelected: state.isSelected, onChange: state.toggle }, ref);
return (
<div {...buttonProps} ref={ref} style={{ padding: '10px', border: '1px solid black', cursor: 'pointer' }}>
{state.isSelected ? 'Активно' : 'Неактивно'}
</div>
);
}
Особенности:
Для реализации заблокированных кнопок используется стандартный
атрибут isDisabled:
let { buttonProps } = useToggleButton({ isSelected: state.isSelected, onChange: state.toggle, isDisabled: true }, ref);
В этом случае:
aria-disabled автоматически добавляется к
элементу.const [master, setMaster] = React.useState(false);
const childStates = [true, false, true].map((val) => useToggleState({ defaultSelected: val }));
const toggleAll = () => {
setMaster(!master);
childStates.forEach((state) => state.setSelected(!master));
};
isPressed можно использовать для запуска анимации
включения/выключения:
<div className={`toggle-slider ${isPressed ? 'on' : 'off'}`}></div>
function ControlledToggle({ selected, onToggle }) {
let ref = React.useRef();
let { buttonProps } = useToggleButton({ isSelected: selected, onChange: onToggle }, ref);
return <button {...buttonProps} ref={ref}>{selected ? 'Вкл' : 'Выкл'}</button>;
}
useToggleState для управления состоянием
внутри компонентов.buttonProps напрямую на рендеримый
элемент.ref, чтобы
сохранялась поддержка клавиатуры.isDisabled для кнопок, блокирующих
взаимодействие.isPressed для
улучшения UX.Эта комбинация обеспечивает корректную доступность, гибкость стилизации и предсказуемое управление состоянием.