Claude Skills Guide

Claude Code for React Native Gesture Handler Guide

Implementing smooth, performant touch interactions is essential for creating polished React Native mobile experiences. React Native Gesture Handler provides a powerful, native-driven solution for handling complex gesture recognition. When combined with Claude Code, you can rapidly implement, debug, and optimize gesture-based interactions in your mobile applications.

This guide walks you through practical patterns for implementing gesture handling with Claude Code assistance.

Understanding React Native Gesture Handler Basics

React Native Gesture Handler replaces the built-in touch system with a more powerful alternative that interfaces directly with the native touch system. It provides gesture recognizers for common interactions like taps, pans, pinches, and rotations.

Core Concepts

Before diving into implementation, understand these fundamental concepts:

Installation

First, ensure gesture handler is installed in your project:

npm install react-native-gesture-handler

For Expo projects:

npx expo install react-native-gesture-handler

Implementing Basic Tap and Pan Gestures

Let’s start with the most common gesture types you’ll use in React Native applications.

Tap Gesture Implementation

A tap gesture detects single or multiple taps on a touchable element. Here’s a practical implementation:

import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';

function TapButton() {
  const scale = useSharedValue(1);
  
  const tapGesture = Gesture.Tap()
    .onBegin(() => {
      scale.value = withSpring(0.95);
    })
    .onFinalize(() => {
      scale.value = withSpring(1);
    })
    .onEnd(() => {
      // Handle tap action here
      console.log('Button tapped!');
    });
  
  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ scale: scale.value }]
  }));
  
  return (
    <GestureDetector gesture={tapGesture}>
      <Animated.View style={[styles.button, animatedStyle]}>
        <Text>Tap Me</Text>
      </Animated.View>
    </GestureDetector>
  );
}

When working with Claude Code, describe the tap behavior you want: “Create a button component that scales down slightly when pressed, then returns to normal with a spring animation. The tap should trigger an onPress callback.”

Pan Gesture for Drag Interactions

Pan gestures enable drag functionality—essential for sliders, card swipes, and drag-and-drop interfaces:

function DraggableCard() {
  const translateX = useSharedValue(0);
  const translateY = useSharedValue(0);
  
  const panGesture = Gesture.Pan()
    .onUpdate((event) => {
      translateX.value = event.translationX;
      translateY.value = event.translationY;
    })
    .onEnd((event) => {
      // Snap back or commit the movement
      if (Math.abs(event.translationX) > 100) {
        // Handle swipe dismiss
        translateX.value = withSpring(event.translationX > 0 ? 300 : -300);
      } else {
        // Return to original position
        translateX.value = withSpring(0);
        translateY.value = withSpring(0);
      }
    });
  
  const animatedStyle = useAnimatedStyle(() => ({
    transform: [
      { translateX: translateX.value },
      { translateY: translateY.value }
    ]
  }));
  
  return (
    <GestureDetector gesture={panGesture}>
      <Animated.View style={[styles.card, animatedStyle]}>
        <Text>Swipe to dismiss</Text>
      </Animated.View>
    </GestureDetector>
  );
}

Combining Multiple Gestures

Real-world applications often need multiple gesture types on the same element or simultaneous gesture recognition.

Simultaneous Gesture Recognition

When you need to recognize multiple gestures at once—for example, allowing both pan and pinch zoom on an image:

function ZoomableImage() {
  const scale = useSharedValue(1);
  const savedScale = useSharedValue(1);
  const translateX = useSharedValue(0);
  const translateY = useSharedValue(0);
  
  const pinchGesture = Gesture.Pinch()
    .onUpdate((event) => {
      scale.value = savedScale.value * event.scale;
    })
    .onEnd(() => {
      savedScale.value = scale.value;
    });
  
  const panGesture = Gesture.Pan()
    .onUpdate((event) => {
      translateX.value = event.translationX;
      translateY.value = event.translationY;
    })
    .onEnd(() => {
      // Clamp or bounds checking here
    });
  
  const composedGesture = Gesture.Simultaneous(pinchGesture, panGesture);
  
  return (
    <GestureDetector gesture={composedGesture}>
      <Animated.Image
        source={require('./image.png')}
        style={[
          styles.image,
          {
            transform: [
              { translateX: translateX.value },
              { translateY: translateY.value },
              { scale: scale.value }
            ]
          }
        ]}
      />
    </GestureDetector>
  );
}

Exclusive Gestures for Competing Interactions

Use Gesture.Exclusive when gestures should not trigger simultaneously—like a pull-to-refresh that shouldn’t interfere with scrolling:

function ScrollViewWithPullToRefresh() {
  const translateY = useSharedValue(0);
  
  const scrollGesture = Gesture.ScrollView();
  
  const refreshGesture = Gesture.Pan()
    .onUpdate((event) => {
      if (event.translationY > 0 && event.velocityY > 0) {
        translateY.value = event.translationY;
      }
    })
    .onEnd((event) => {
      if (event.translationY > 100) {
        // Trigger refresh
        translateY.value = withSpring(0);
      } else {
        translateY.value = withSpring(0);
      }
    });
  
  const gesture = Gesture.Exclusive(refreshGesture, scrollGesture);
  
  return (
    <GestureDetector gesture={gesture}>
      <Animated.ScrollView>
        {/* Content */}
      </Animated.ScrollView>
    </GestureDetector>
  );
}

Best Practices for Gesture Implementation

Follow these guidelines for smooth, performant gesture handling in your React Native applications.

Performance Optimization

Accessibility Considerations

Testing Gesture Behavior

Claude Code can help you write tests for gesture interactions:

import { fireEvent } from '@testing-library/react-native';

test('draggable card responds to pan gesture', () => {
  const onDragEnd = jest.fn();
  const { getByText } = render(<DraggableCard onDragEnd={onDragEnd} />);
  
  const card = getByText('Swipe to dismiss');
  
  // Simulate a pan gesture
  fireEvent(card, 'onLayout', {
    nativeEvent: { layout: { x: 0, y: 0, width: 300, height: 200 } }
  });
  
  fireEvent(card, 'onResponderGrant', { nativeEvent: { touches: [{ pageX: 50, pageY: 100 }] }});
  fireEvent(card, 'onResponderMove', { nativeEvent: { touches: [{ pageX: 200, pageY: 100 }] }});
  fireEvent(card, 'onResponderRelease', { nativeEvent: { touches: [{ pageX: 200, pageY: 100 }] }});
  
  expect(onDragEnd).toHaveBeenCalled();
});

Common Gesture Handler Patterns

Claude Code excels at generating these common patterns for your projects:

  1. Swipeable list items: Create dismissible or action-revealing list rows
  2. Image galleries: Implement pinch-to-zoom and pan navigation
  3. Form inputs: Build custom sliders, color pickers, and rating components
  4. Gesture-based navigation: Implement swipe-back, page transitions, and drawer navigation
  5. Drawing and signature: Capture freeform touch input for signatures or sketching

When requesting these from Claude Code, be specific about the gesture types, animation preferences, and edge cases you need to handle.

Debugging Gesture Issues

Common problems and solutions when working with React Native Gesture Handler:

Conclusion

React Native Gesture Handler combined with Reanimated provides a powerful foundation for building sophisticated touch interactions. When you use Claude Code to generate and debug these patterns, you can rapidly implement gesture-based features while maintaining clean, performant code.

Start with simple tap and pan gestures, then progressively add more complex interactions as you become comfortable with the gesture composition patterns. Remember to prioritize accessibility and test your gesture implementations thoroughly across different devices.

With these patterns and Claude Code as your development partner, you’ll be building polished gesture-driven interfaces in no time.

Built by theluckystrike — More at zovo.one