--- title: Use GestureDetector for Animated Press States impact: MEDIUM impactDescription: UI thread animations, smoother press feedback tags: animation, gestures, press, reanimated --- ## Use GestureDetector for Animated Press States For animated press states (scale, opacity on press), use `GestureDetector` with `Gesture.Tap()` and shared values instead of Pressable's `onPressIn`/`onPressOut`. Gesture callbacks run on the UI thread as worklets—no JS thread round-trip for press animations. **Incorrect (Pressable with JS thread callbacks):** ```tsx import { Pressable } from "react-native"; import Animated, { useSharedValue, useAnimatedStyle, withTiming } from "react-native-reanimated"; function AnimatedButton({ onPress }: { onPress: () => void }) { const scale = useSharedValue(1); const animatedStyle = useAnimatedStyle(() => ({ transform: [{ scale: scale.value }], })); return ( (scale.value = withTiming(0.95))} onPressOut={() => (scale.value = withTiming(1))} > Press me ); } ``` **Correct (GestureDetector with UI thread worklets):** ```tsx import { Gesture, GestureDetector } from "react-native-gesture-handler"; import Animated, { useSharedValue, useAnimatedStyle, withTiming, interpolate, runOnJS, } from "react-native-reanimated"; function AnimatedButton({ onPress }: { onPress: () => void }) { // Store the press STATE (0 = not pressed, 1 = pressed) const pressed = useSharedValue(0); const tap = Gesture.Tap() .onBegin(() => { pressed.set(withTiming(1)); }) .onFinalize(() => { pressed.set(withTiming(0)); }) .onEnd(() => { runOnJS(onPress)(); }); // Derive visual values from the state const animatedStyle = useAnimatedStyle(() => ({ transform: [{ scale: interpolate(withTiming(pressed.get()), [0, 1], [1, 0.95]) }], })); return ( Press me ); } ``` Store the press **state** (0 or 1), then derive the scale via `interpolate`. This keeps the shared value as ground truth. Use `runOnJS` to call JS functions from worklets. Use `.set()` and `.get()` for React Compiler compatibility. Reference: [Gesture Handler Tap Gesture](https://docs.swmansion.com/react-native-gesture-handler/docs/gestures/tap-gesture)