tezvyn:

Draggable Snap-Back Card with Gesture Handler and Reanimated

AI-drafted, machine-checkedSource: interviewintermediate
WHAT IT TESTS

gesture-driven animation.

OUTLINE

shared values track offset, a Pan gesture updates them on the UI thread, an animated style applies translation, onEnd springs back to zero.

WHAT THIS TESTS Whether you can compose gesture-handler and Reanimated so the drag runs on the UI thread, not the JS thread.

A GOOD ANSWER COVERS Create shared values with useSharedValue for the x and y translation, and optionally a saved-offset value to accumulate movement. Define a pan gesture with Gesture.Pan: its onChange or onUpdate worklet adds the event translation to the starting offset and writes it to the shared values, and its onEnd worklet sets the shared values back to zero using withSpring so the card springs smoothly back to origin. Build an animated style with useAnimatedStyle that returns a transform array using the shared values, and apply it to an Animated.View. Wrap that view in a GestureDetector with the gesture. Because the gesture callbacks are worklets running on the UI thread and the shared values drive the animated style directly, the drag and snap-back happen entirely off the JS thread, staying smooth even under JS load. Wrap the app or screen in GestureHandlerRootView so gestures work.

COMMON WRONG ANSWERS Storing the position in useState and calling setState on every move, which floods the JS thread and stutters. Using the Animated API from core React Native expecting the same off-thread behavior. Forgetting GestureHandlerRootView. Not resetting the offset, so the card drifts on repeated drags.

LIKELY FOLLOW-UPS Why worklets run on the UI thread and what runOnJS is for. The difference between withSpring and withTiming for the snap. How to add a threshold so the card dismisses past a distance instead of snapping back.

ONE CONCRETE EXAMPLE translateX and translateY are shared values. The Pan gesture's onChange sets them to the accumulated offset plus event translation; onEnd assigns withSpring(0) to both. useAnimatedStyle returns transform with those values, applied to an Animated.View inside a GestureDetector, so dragging and the springy snap-back run on the UI thread.

Read the original → docs.swmansion.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.