Bird
Raised Fist0
React Nativemobile~20 mins

Gesture Handler integration in React Native - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Swipeable Box
A screen with a colored box that you can swipe left or right. The box changes color based on swipe direction.
Target UI
┌─────────────────────────────┐
│ Swipe the box left or right │
│                             │
│        ┌───────────┐        │
│        │           │        │
│        │   BOX     │        │
│        │           │        │
│        └───────────┘        │
│                             │
└─────────────────────────────┘
Use react-native-gesture-handler to detect horizontal swipes on the box.
The box should start with a gray background.
Swiping right changes the box color to green.
Swiping left changes the box color to red.
The box should smoothly animate color changes.
Use functional components and hooks.
Starter Code
React Native
import React, { useState } from 'react';
import { View, Text, StyleSheet, Animated } from 'react-native';
import { GestureDetector, Gesture } from 'react-native-gesture-handler';

export default function SwipeableBox() {
  const [boxColor, setBoxColor] = useState('gray');

  // TODO: Define swipe gesture here

  return (
    <View style={styles.container}>
      <Text style={styles.instructions}>Swipe the box left or right</Text>
      {/* TODO: Wrap box with GestureDetector and apply gesture */}
      <Animated.View style={[styles.box, { backgroundColor: boxColor }]} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff'
  },
  instructions: {
    fontSize: 18,
    marginBottom: 20
  },
  box: {
    width: 150,
    height: 150,
    borderRadius: 10
  }
});
Task 1
Task 2
Task 3
Task 4
Solution
React Native
import React, { useState, useRef } from 'react';
import { View, Text, StyleSheet, Animated } from 'react-native';
import { GestureDetector, Gesture } from 'react-native-gesture-handler';

export default function SwipeableBox() {
  const [boxColor, setBoxColor] = useState('gray');
  const animatedColor = useRef(new Animated.Value(0)).current; // 0=gray, 1=green, -1=red

  const colorInterpolation = animatedColor.interpolate({
    inputRange: [-1, 0, 1],
    outputRange: ['red', 'gray', 'green']
  });

  const swipeGesture = Gesture.Pan()
    .onEnd(event => {
      if (event.translationX > 50) {
        setBoxColor('green');
        Animated.timing(animatedColor, {
          toValue: 1,
          duration: 300,
          useNativeDriver: false
        }).start();
      } else if (event.translationX < -50) {
        setBoxColor('red');
        Animated.timing(animatedColor, {
          toValue: -1,
          duration: 300,
          useNativeDriver: false
        }).start();
      } else {
        setBoxColor('gray');
        Animated.timing(animatedColor, {
          toValue: 0,
          duration: 300,
          useNativeDriver: false
        }).start();
      }
    });

  return (
    <View style={styles.container}>
      <Text style={styles.instructions}>Swipe the box left or right</Text>
      <GestureDetector gesture={swipeGesture}>
        <Animated.View style={[styles.box, { backgroundColor: colorInterpolation }]} />
      </GestureDetector>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff'
  },
  instructions: {
    fontSize: 18,
    marginBottom: 20
  },
  box: {
    width: 150,
    height: 150,
    borderRadius: 10
  }
});

This solution uses react-native-gesture-handler to detect horizontal swipe gestures on the box. We create a Pan gesture that listens for the end of the swipe. If the user swipes right more than 50 pixels, the box color changes to green. If swiped left more than 50 pixels, it changes to red. Otherwise, it resets to gray.

We use React Native's Animated.Value to smoothly interpolate the background color between red, gray, and green. The Animated.timing function animates the color change over 300 milliseconds.

The box is wrapped inside a GestureDetector component that applies the gesture to it. This setup ensures the box responds visually and interactively to user swipes.

Final Result
Completed Screen
┌─────────────────────────────┐
│ Swipe the box left or right │
│                             │
│        ┌───────────┐        │
│        │           │        │
│        │   BOX     │        │
│        │           │        │
│        └───────────┘        │
│                             │
└─────────────────────────────┘
Swiping the box right changes its color smoothly to green.
Swiping the box left changes its color smoothly to red.
Swiping less than 50 pixels resets the box color to gray.
Stretch Goal
Add a reset button below the box that resets the box color to gray when tapped.
💡 Hint
Use a TouchableOpacity with a Text label 'Reset' and onPress handler to set boxColor state to 'gray' and animate the color back.

Practice

(1/5)
1. What is the main purpose of wrapping your React Native app with GestureHandlerRootView?
easy
A. To enable gesture detection and handling throughout the app
B. To style the app's background color
C. To improve app performance by caching views
D. To add navigation capabilities between screens

Solution

  1. Step 1: Understand the role of GestureHandlerRootView

    This component is required to wrap the app so that gesture detection works properly across all child components.
  2. Step 2: Differentiate from other purposes

    Styling, performance caching, or navigation are unrelated to GestureHandlerRootView's function.
  3. Final Answer:

    To enable gesture detection and handling throughout the app -> Option A
  4. Quick Check:

    GestureHandlerRootView enables gestures [OK]
Hint: GestureHandlerRootView enables gestures app-wide [OK]
Common Mistakes:
  • Thinking it styles the app
  • Confusing it with navigation setup
  • Assuming it improves performance
2. Which of the following is the correct way to import the TapGestureHandler from react-native-gesture-handler?
easy
A. import { TapGestureHandler } from 'react-native';
B. import TapGestureHandler from 'react-native-gesture-handler';
C. import { TapGestureHandler } from 'react-native-gesture-handler';
D. import TapGestureHandler from 'react-native-gesture-handler/TapGestureHandler';

Solution

  1. Step 1: Recall correct import syntax

    TapGestureHandler is a named export from 'react-native-gesture-handler', so it must be imported with curly braces.
  2. Step 2: Eliminate incorrect imports

    Default import without braces is wrong, importing from 'react-native' is incorrect, and importing from a subpath is not standard.
  3. Final Answer:

    import { TapGestureHandler } from 'react-native-gesture-handler'; -> Option C
  4. Quick Check:

    Named imports use curly braces [OK]
Hint: Use curly braces for named imports like TapGestureHandler [OK]
Common Mistakes:
  • Using default import instead of named import
  • Importing from 'react-native' instead of gesture-handler
  • Trying to import from a subpath
3. Given this code snippet, what will happen when the user taps the blue box?
import { TapGestureHandler, GestureHandlerRootView } from 'react-native-gesture-handler';
import React from 'react';
import { View, Text, Alert } from 'react-native';

export default function App() {
  const onTap = () => Alert.alert('Box tapped!');

  return (
    
      
        
      
    
  );
}
medium
A. An alert saying 'Box tapped!' will appear when the blue box is tapped
B. Nothing happens because onActivated is not a valid prop
C. The app will crash due to missing gesture handler setup
D. The blue box changes color when tapped

Solution

  1. Step 1: Understand TapGestureHandler usage

    The onActivated prop triggers the callback when the tap gesture is recognized.
  2. Step 2: Analyze the code behavior

    When the blue box is tapped, the onTap function runs, showing an alert with 'Box tapped!'.
  3. Final Answer:

    An alert saying 'Box tapped!' will appear when the blue box is tapped -> Option A
  4. Quick Check:

    onActivated triggers alert on tap [OK]
Hint: onActivated fires callback on tap gesture [OK]
Common Mistakes:
  • Confusing onActivated with onPress
  • Assuming no effect without extra setup
  • Expecting color change without code
4. You wrote this code but the tap gesture is not detected. What is the likely cause?
import { TapGestureHandler } from 'react-native-gesture-handler';
import React from 'react';
import { View } from 'react-native';

export default function App() {
  const onTap = () => console.log('Tapped');

  return (
    
      
    
  );
}
medium
A. The style width and height are too small for detection
B. The app is missing the GestureHandlerRootView wrapper
C. The View component must be a Button for gestures
D. The onActivated prop should be onPress instead

Solution

  1. Step 1: Check for GestureHandlerRootView presence

    Gesture handlers require the app to be wrapped in GestureHandlerRootView to work properly.
  2. Step 2: Evaluate other options

    onActivated is correct, View can detect gestures, and size 100x100 is sufficient.
  3. Final Answer:

    The app is missing the GestureHandlerRootView wrapper -> Option B
  4. Quick Check:

    Missing GestureHandlerRootView blocks gestures [OK]
Hint: Always wrap app with GestureHandlerRootView [OK]
Common Mistakes:
  • Using onPress instead of onActivated
  • Thinking View can't detect gestures
  • Assuming size is too small
5. You want to detect both tap and long press gestures on the same box using react-native-gesture-handler. Which approach correctly integrates both handlers?
hard
A. Use only TapGestureHandler with a long delay prop
B. Use PanGestureHandler instead for both tap and long press
C. Wrap the box in two sibling gesture handlers without nesting
D. Nest LongPressGestureHandler inside TapGestureHandler and handle callbacks separately

Solution

  1. Step 1: Understand gesture handler nesting

    To detect multiple gestures on the same view, nest handlers so gestures can be recognized distinctly.
  2. Step 2: Evaluate options

    Using only TapGestureHandler can't detect long press, siblings won't work well on same view, PanGestureHandler is for drag gestures.
  3. Final Answer:

    Nest LongPressGestureHandler inside TapGestureHandler and handle callbacks separately -> Option D
  4. Quick Check:

    Nesting handlers enables multiple gesture detection [OK]
Hint: Nest handlers to detect multiple gestures on one view [OK]
Common Mistakes:
  • Trying to detect long press with TapGestureHandler only
  • Using sibling handlers on same view without nesting
  • Confusing PanGestureHandler with tap/long press
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard