React Aria предоставляет мощный набор хуков и утилит для управления
пользовательскими взаимодействиями, включая обработку касаний на
мобильных и сенсорных устройствах. Основной принцип заключается в
абстрагировании сложностей нативных событий touchstart,
touchmove, touchend и touchcancel
в удобные React-хуки, которые работают согласованно на разных платформах
и браузерах.
usePress для касанийХук usePress позволяет отслеживать нажатия и касания на
интерактивных элементах. Он объединяет события мыши, клавиатуры и
сенсорного экрана, обеспечивая единый интерфейс.
import {usePress} from '@react-aria/interactions';
import {useRef} from 'react';
function TouchButton() {
let ref = useRef();
let {pressProps, isPressed} = usePress({
onPressStart: () => console.log('Начало касания'),
onPressEnd: () => console.log('Конец касания'),
onPress: () => console.log('Нажатие завершено')
});
return (
<button {...pressProps} ref={ref}>
{isPressed ? 'Нажато' : 'Нажми меня'}
</button>
);
}
Ключевые моменты:
onPressStart срабатывает сразу при касании, до
отпускания.onPressEnd вызывается при завершении касания, даже если
элемент был перемещен.onPress срабатывает только если касание завершилось на
том же элементе, что и начало.useDragДля сложных интерактивных элементов, таких как слайдеры или
перетаскиваемые панели, React Aria предлагает useDrag. Он
отслеживает движение пальца и преобразует его в данные о смещении и
скорости.
import {useDrag} from '@react-aria/interactions';
import {useRef, useState} from 'react';
function DraggableBox() {
let ref = useRef();
let [position, setPosition] = useState({x: 0, y: 0});
let {dragProps} = useDrag({
onDragMove: (e) => setPosition({
x: position.x + e.delta.x,
y: position.y + e.delta.y
}),
onDragEnd: (e) => console.log('Перетаскивание завершено', e)
});
return (
<div
{...dragProps}
ref={ref}
style={{
width: 100,
height: 100,
backgroundColor: 'salmon',
transform: `translate(${position.x}px, ${position.y}px)`
}}
/>
);
}
Особенности работы:
onDragMove обеспечивает плавное перемещение,
автоматически учитывая устройство ввода.delta — смещение за текущее событие движения, полезно
для плавных анимаций.onDragEnd вызывается при завершении касания или
отпускании мыши.React Aria стремится к универсальности интерфейсов, поэтому многие
хуки для сенсорных событий работают и с клавиатурой. Это позволяет
создавать доступные компоненты без отдельной логики для
keydown или keyup.
Пример объединенного обработчика:
import {usePress} from '@react-aria/interactions';
import {useRef} from 'react';
function AccessibleCard() {
let ref = useRef();
let {pressProps} = usePress({
onPress: () => alert('Элемент активирован')
});
return (
<div {...pressProps} ref={ref} tabIndex={0} style={{padding: 20, border: '1px solid gray'}}>
Нажмите или коснитесь
</div>
);
}
tabIndex={0} делает компонент доступным для навигации с
клавиатуры.useHover и useFocusДля комплексных сенсорных интерфейсов важно различать простое касание и наведение или фокус:
useHover отслеживает наведение пальца на сенсорных
экранах и мыши.useFocus управляет фокусом и может использоваться для
визуальных эффектов при выделении.import {useHover} from '@react-aria/interactions';
import {useRef, useState} from 'react';
function HoverableBox() {
let ref = useRef();
let [hovered, setHovered] = useState(false);
let {hoverProps} = useHover({
onHoverStart: () => setHovered(true),
onHoverEnd: () => setHovered(false)
});
return (
<div
{...hoverProps}
ref={ref}
style={{
width: 120,
height: 120,
backgroundColor: hovered ? 'lightblue' : 'lightgray'
}}
/>
);
}
usePress и useDrag
минимизирует задержку между касанием и реакцией интерфейса.requestAnimationFrame внутри
onDragMove.useRef для
хранения состояния позиции.React Aria превращает обработку касаний в предсказуемый и совместимый
с различными устройствами процесс, обеспечивая единый API для мыши,
клавиатуры и сенсорного ввода. Правильное использование
usePress, useDrag, useHover и
useFocus позволяет создавать интерактивные, доступные и
отзывчивые интерфейсы без сложной низкоуровневой логики.