useButton — это хук из библиотеки React
Aria, предназначенный для управления поведением кнопок и
обеспечения доступности (accessibility) в приложениях на
React. Он инкапсулирует стандартные практики ARIA,
управление событиями и клавиатурные взаимодействия, освобождая
разработчика от необходимости вручную писать сложные обработчики.
Хук подходит не только для обычных <button>, но и
для кастомных элементов, имитирующих кнопки (например,
<div> или <span> с ролью
button).
import { useButton } from '@react-aria/button';
import { useRef } from 'react';
function MyButton(props) {
let ref = useRef();
let { buttonProps, isPressed } = useButton(props, ref);
return (
<button {...buttonProps} ref={ref}>
{isPressed ? 'Нажата' : 'Нажмите меня'}
</button>
);
}
Ключевые моменты:
buttonProps — объект с готовыми пропсами для кнопки,
включающий обработчики событий и ARIA-атрибуты.ref — ссылка на DOM-элемент, обязательная для
корректной работы хука.isPressed — булевый флаг, указывающий на состояние
нажатия кнопки.Если кнопка реализуется не через <button>, а через
произвольный элемент, важно добавить role="button" и
правильно обработать клавиатурные события:
function CustomButton(props) {
let ref = useRef();
let { buttonProps, isPressed } = useButton(props, ref);
return (
<div {...buttonProps} ref={ref} role="button" tabIndex={0} style={{ padding: '8px', border: '1px solid black', display: 'inline-block' }}>
{isPressed ? 'Активно' : 'Кликни'}
</div>
);
}
Особенности:
tabIndex={0} позволяет элементу быть фокусируемым через
клавиатуру.Enter и
Space для активации кнопки.useButton упрощает работу с основными событиями:
onPress — срабатывает при клике или активации через
клавиатуру.onPressStart и onPressEnd — для
отслеживания начала и конца нажатия.onPressChange — вызывается при смене состояния нажатия
(true / false).function AdvancedButton() {
let ref = useRef();
let { buttonProps, isPressed } = useButton({
onPress: () => console.log('Кнопка активирована'),
onPressStart: () => console.log('Начало нажатия'),
onPressEnd: () => console.log('Конец нажатия'),
}, ref);
return <button {...buttonProps} ref={ref}>{isPressed ? 'Нажата' : 'Кнопка'}</button>;
}
Важно: onPress объединяет мышь,
клавиатуру и сенсорные устройства в одно событие, обеспечивая
универсальное поведение.
useButton автоматически добавляет:
aria-pressed для кнопок типа toggle.disabled для неактивных кнопок.Enter и Space) для
кастомных элементов.function ToggleButton() {
let ref = useRef();
let [isSelected, setIsSelected] = useState(false);
let { buttonProps } = useButton({
onPress: () => setIsSelected(!isSelected),
isPressed: isSelected
}, ref);
return <button {...buttonProps} ref={ref}>{isSelected ? 'Включено' : 'Выключено'}</button>;
}
Выделение ключевых моментов:
aria-pressed.isDisabled в
пропсах.usePress: можно
комбинировать с низкоуровневым хуком usePress для детальной
настройки поведения нажатия.function IconButton({ icon, label, onClick }) {
let ref = useRef();
let { buttonProps, isPressed } = useButton({ onPress: onClick }, ref);
return (
<div {...buttonProps} ref={ref} role="button" aria-label={label} tabIndex={0} style={{
display: 'inline-flex',
alignItems: 'center',
padding: '6px',
border: '1px solid gray',
background: isPressed ? '#eee' : '#fff',
cursor: 'pointer'
}}>
{icon}
</div>
);
}
Особенности:
aria-label обеспечивает корректное озвучивание кнопки
для скринридеров.isPressed позволяет визуально отображать
нажатие.<button>.useButtonref на DOM-элемент.role="button" и
tabIndex={0}.onPress вместо onClick для
универсального поведения.isPressed для
синхронизации состояния с ARIA.useButton обеспечивает безопасное и доступное управление
кнопками в React-приложениях, сокращая код и соблюдая стандарты ARIA без
необходимости вручную прописывать события и атрибуты.