Skip to main content
Version: 3.x

Getting started

Gesture Handler provides a declarative API exposing the native platform's touch and gesture system to React Native. It's designed to be a replacement of React Native's built in touch system called Gesture Responder System. Using native touch handling allows addressing the performance limitations of React Native's Gesture Responder System. It also provides more control over the platform's native components that can handle gestures on their own.

Installation

Requirements

Compatibility with React Native versions

react-native-gesture-handler supports the three latest minor releases of react-native.

0.820.830.840.850.86
3.1.x
no
yes
yes
yes
yes
3.0.x
yes
yes
yes
yes
yes

Running gestures on the UI thread

Using Reanimated is the recommended method of handling gesture-driven interactions on the UI thread. In order to use it, you need to install react-native-reanimated along with react-native-worklets. Another approach is to use React Native's Animated API.

For more details on how to implement these, refer to the dedicated sections for Reanimated and Animated.

Setup

Setting up react-native-gesture-handler is pretty straightforward:

1. Start with installing the package from npm:

npm install react-native-gesture-handler

2. Wrap your app with GestureHandlerRootView component

import { GestureHandlerRootView } from 'react-native-gesture-handler';

export default function App() {
return (
<GestureHandlerRootView>
<ActualApp />
</GestureHandlerRootView>
);
}

Keep GestureHandlerRootView as close to the actual root of the app as possible. It's the entry point for all gestures and all gesture relations. The gestures won't be recognized outside of the root view, and relations only work between gestures mounted under the same root view.

Check out GestureHandlerRootView section for more details.

3. Platform specific setup

Expo development build

When using an Expo development build, run prebuild to update the native code in the ios and android directories.

npx expo prebuild
Android

Setting up Gesture Handler on Android doesn't require any more steps. Keep in mind that if you want to use gestures in Modals you need to wrap Modal's content with GestureHandlerRootView:

import { Modal } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';

export function CustomModal({ children, ...rest }) {
return (
<Modal {...rest}>
<GestureHandlerRootView>{children}</GestureHandlerRootView>
</Modal>
);
}
iOS

While developing for iOS, make sure to install pods first before running the app:

cd ios && bundle install && bundle exec pod install && cd ..
macOS

While developing for macOS, make sure to install pods first before running the app:

cd macos && bundle install && bundle exec pod install && cd ..
Web

There is no additional configuration required for the web.

With wix/react-native-navigation

If you are using a native navigation library like wix/react-native-navigation you need to make sure that every screen is wrapped with GestureHandlerRootView. This can be done for example at the stage when you register your screens. Here's an example:

import { Navigation } from 'react-native-navigation';
import FirstTabScreen from './FirstTabScreen';
import SecondTabScreen from './SecondTabScreen';
import PushedScreen from './PushedScreen';

// Register all screens of the app (including internal ones)
export function registerScreens() {
Navigation.registerComponent(
'example.FirstTabScreen',
() => {
return (
<GestureHandlerRootView>
<FirstTabScreen />
</GestureHandlerRootView>
);
},
() => FirstTabScreen
);
Navigation.registerComponent(
'example.SecondTabScreen',
() => {
return (
<GestureHandlerRootView>
<SecondTabScreen />
</GestureHandlerRootView>
);
},
() => SecondTabScreen
);
Navigation.registerComponent(
'example.PushedScreen',
() => {
return (
<GestureHandlerRootView>
<PushedScreen />
</GestureHandlerRootView>
);
},
() => PushedScreen
);
}

You can check out this example project to see this kind of set up in action.

Your first gesture

With the setup done, you're ready to add your first gesture. Create a tap gesture with the useTapGesture hook, attach it to a component with GestureDetector. Don't forget to wrap your app with GestureHandlerRootView, as described in previous section.

import { StyleSheet, View } from 'react-native';
import {
GestureDetector,
GestureHandlerRootView,
useTapGesture,
} from 'react-native-gesture-handler';

export default function App() {
const tap = useTapGesture({
onActivate: () => {
console.log('Tapped!');
},
});

return (
<GestureHandlerRootView style={styles.container}>
<GestureDetector gesture={tap}>
<View style={styles.box} />
</GestureDetector>
</GestureHandlerRootView>
);

That's it! The gesture fires onActivate whenever a tap is recognized. Check out Gesture callbacks & events for the full set of callbacks, or browse all gestures to keep exploring.