Что вы знаете о gesture handling в React Native?
Gesture handling (обработка жестов) в React Native — это механизм взаимодействия пользователя с интерфейсом через касания, свайпы, перетаскивания, пинчи и другие жесты. Это особенно важно в мобильных приложениях, где управление осуществляется в основном через сенсорный экран.
React Native предоставляет несколько способов работы с жестами, но наиболее мощным и производительным считается использование библиотеки react-native-gesture-handler. Она расширяет стандартные возможности и работает более плавно, особенно при использовании с Reanimated.
Почему стандартные обработчики не всегда подходят
React Native по умолчанию использует обработчики на базе JavaScript (onPress, onLongPress, onPanResponder), но у них есть ограничения:
-
Все события проходят через JavaScript-поток, что может вызывать лаги на слабых устройствах
-
Сложно реализовать сложные и конкурентные жесты (например, одновременный свайп и pinch-to-zoom)
-
Нет нативной интеграции с системой жестов iOS и Android (nested scroll, gestures prioritization)
react-native-gesture-handler
Эта библиотека реализует жесты на уровне нативного кода, минуя JS-поток, что обеспечивает высокую производительность, приоритеты жестов и интеграцию с другими нативными компонентами (например, ScrollView).
Установка:
npm install react-native-gesture-handler
Для bare workflow в React Native требуется также добавить обёртку в App.js:
import 'react-native-gesture-handler';
И обернуть корневой компонент:
import { GestureHandlerRootView } from 'react-native-gesture-handler';
function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<NavigationContainer>
<YourApp />
</NavigationContainer>
</GestureHandlerRootView>
);
}
Базовые компоненты библиотеки
react-native-gesture-handler предоставляет множество жестов, каждый из которых — компонент-обёртка:
Компонент | Назначение |
---|---|
TapGestureHandler | Одинарный или двойной тап |
--- | --- |
PanGestureHandler | Перемещение/свайп/drag |
--- | --- |
LongPressGestureHandler | Долгое нажатие |
--- | --- |
PinchGestureHandler | Увеличение/уменьшение двумя пальцами (пинч) |
--- | --- |
RotationGestureHandler | Поворот (двумя пальцами) |
--- | --- |
FlingGestureHandler | Быстрый свайп (флик) |
--- | --- |
Пример: TapGestureHandler
import { TapGestureHandler } from 'react-native-gesture-handler';
function Example() {
const onSingleTap = () => {
console.log('Tapped');
};
return (
<TapGestureHandler onActivated={onSingleTap}>
<View style={{ height: 100, width: 100, backgroundColor: 'skyblue' }} />
</TapGestureHandler>
);
}
PanGestureHandler — свайпы и drag
import { PanGestureHandler } from 'react-native-gesture-handler';
import Animated, {
useAnimatedGestureHandler,
useAnimatedStyle,
useSharedValue,
} from 'react-native-reanimated';
function DraggableBox() {
const translateX = useSharedValue(0);
const translateY = useSharedValue(0);
const panGesture = useAnimatedGestureHandler({
onActive: (event) => {
translateX.value = event.translationX;
translateY.value = event.translationY;
},
onEnd: () => {
// можно добавить возвращение на место или физику
}
});
const animatedStyle = useAnimatedStyle(() => ({
transform: \[
{ translateX: translateX.value },
{ translateY: translateY.value }
\]
}));
return (
<PanGestureHandler onGestureEvent={panGesture}>
<Animated.View
style={\[{ width: 100, height: 100, backgroundColor: 'tomato' }, animatedStyle\]}
/>
</PanGestureHandler>
);
}
Объединение жестов
С помощью GestureDetector и API Gesture из Reanimated 2.3+ можно объединять несколько жестов:
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
const tap = Gesture.Tap().onEnd(() => {
console.log('Tapped');
});
const pan = Gesture.Pan().onUpdate((e) => {
console.log('Pan:', e.translationX, e.translationY);
});
const composed = Gesture.Race(tap, pan); // или Gesture.Simultaneous()
<GestureDetector gesture={composed}>
<Animated.View style={...} />
</GestureDetector>
Работа с навигацией
React Navigation (начиная с версии 5) использует react-native-gesture-handler для реализации свайпов назад (на iOS), drawer меню, tab свайпов. Поэтому важно правильно подключить GestureHandlerRootView и NavigationContainer.
Советы по работе с жестами
-
Не забывайте оборачивать экран в GestureHandlerRootView — иначе жесты не будут работать.
-
Используйте Animated.View из react-native-reanimated для плавных анимаций.
-
Для сложных взаимодействий комбинируйте жесты с Gesture.Simultaneous, Gesture.Exclusive, Gesture.Race.
-
Разделяйте обработку касаний и жестов — TouchableOpacity и TapGestureHandler могут конфликтовать, если используются вместе.
-
Следите за приоритетами жестов — можно использовать waitFor, simultaneousWith и другие свойства для управления вложенными жестами.
Gesture handling — одна из самых мощных сторон React Native, особенно в сочетании с Reanimated. Она позволяет создавать нативные, отзывчивые и плавные интерфейсы, включая drag'n'drop, кастомные свайпы, pinch-to-zoom, pull-to-refresh и другие интерактивные паттерны пользовательского взаимодействия.