Pan Responder

    Most React Native components, like View, can handle touch/click events. However, the APIs for doing this are fairly low level, so we rarely use them directly. Instead, we use the PanResponder API, which is a higher level abstraction for handling touch/click events.

    API

    Only a single component can respond to touch events at one time - the component responding to events owns a global "interaction lock". The PanResponder API helps us manage what component owns this lock through a set of callbacks. Each of these callbacks is also passed an event and gestureState object containing info about the touch events (e.g. position and velocity).

    To create a PanResponder, we call PanResponder.create(callbacksObject). The result is a set of props that can be passed to View as props (these are the lower-level touch event handling props). We'll typically wrap the result with useRef, since we only want to create a single PanResponder for the lifecycle of the component.

    The full set of callbacks we can pass is:

    • onStartShouldSetPanResponder: (event, gestureState) => {}
    • onStartShouldSetPanResponderCapture: (event, gestureState) => {}
    • onMoveShouldSetPanResponder: (event, gestureState) => {}
    • onMoveShouldSetPanResponderCapture: (event, gestureState) => {}
    • onPanResponderReject: (event, gestureState) => {}
    • onPanResponderGrant: (event, gestureState) => {}
    • onPanResponderStart: (event, gestureState) => {}
    • onPanResponderEnd: (event, gestureState) => {}
    • onPanResponderRelease: (event, gestureState) => {}
    • onPanResponderMove: (event, gestureState) => {}
    • onPanResponderTerminate: (event, gestureState) => {}
    • onPanResponderTerminationRequest: (event, gestureState) => {}
    • onShouldBlockNativeResponder: (event, gestureState) => {}

    Example

    In this example, we'll use PanResponder to create a drag interaction. There are 3 parts:

    • pan.js - This contains a reducer function for managing the state of the drag (we use the conventions from the managing data with useReducer section)
    • usePanResponder.js - A custom hook that creates a PanResponder with a set of callbacks for managing the gesture and updating the state of the drag via useReducer.
    • App.js - We call our custom usePanResponder hook, passing the created panHandlers into a View, and using the drag state to update the style.

    In a real app, we should generally use Animated.Values in our style for better performance. E.g. create a positionY animated value from initialY and offsetY, and start a .timing animation with a very short duration whenever the state of the drag changes.

    Contents
    1. API
    2. Example

    Want to learn React Native in-depth?

    If you like React Native Express, you'll love my new book, Fullstack React Native: The complete guide to React Native! Throughout the book, we'll build 7 full apps, covering complex topics like navigation, gestures, and native modules. We don't assume any knowledge of React or newer JavaScript language features, so you can dive right in regardless of your experience level. The book comes in PDF, EPUB and MOBI formats.

    Looking for more help?

    Infinite Red sponsors React Native Express and is the premier React Native agency. They're also the team behind the React Native newsletter, podcast, and conference listed here. Get in touch at infinite.red/react-native for a proposal on your next project!