Skip to main content
Version: 1.x (Reanimated 4)

Drag & Drop

Add draggable to any node and it follows your finger. Position updates run on the UI thread, so dragging stays smooth even under JS-thread load.

<Circle x={120} y={120} radius={50} fill="#8a2be2" draggable />

Enabling drag

Dragging is opt-in per node. Set the flag on any node you want to move:

PropDefaultEnables
draggablefalseOne-finger drag.
dragDistance3Pixels of movement before a drag starts.

draggable is independent of the scale and rotate flags (see Multi-touch Gestures), so a node can be draggable without being scalable or rotatable, and the other way around.

Drag lifecycle

HandlerFires when
onDragStartMovement passes the dragDistance threshold.
onDragMoveOn each move while dragging.
onDragEndThe finger lifts.
<Circle
x={120}
y={120}
radius={50}
fill="#8a2be2"
draggable
onDragStart={() => setActive(true)}
onDragEnd={(e) => {
setActive(false);
const { x, y } = e.currentTarget.getAbsolutePosition();
console.log('dropped at', x, y);
}}
/>
Drag lifecycle

Activation threshold

dragDistance (default 3) is how many pixels the finger must move before a drag begins; this keeps taps from being misread as tiny drags. Raise it for "stickier" taps:

<Rect
x={40}
y={40}
width={100}
height={100}
fill="#22d3ee"
draggable
dragDistance={25}
/>
Activation threshold

Persisting position

Dragging moves the node live via internal shared values. When the gesture ends, commit the final transform to your React state so the position survives re-renders; this is also what a Transformer expects:

const [pos, setPos] = useState({ x: 120, y: 120 });

<Circle
x={pos.x}
y={pos.y}
radius={50}
fill="#8a2be2"
draggable
onDragEnd={(e) => {
const p = e.currentTarget.getAbsolutePosition();
setPos({ x: p.x, y: p.y });
}}
/>;

onDragEnd captures position only. If the node can also be scaled or rotated, prefer onTransformEnd: it reports every kind of transform (position, scale, and rotation) in one handler, and fires from both the node and an attached Transformer. See Persisting the result.

Dragging groups

draggable works on a Group too, moving the whole group (and its children) as one:

<Group x={100} y={100} draggable>
<Rect x={0} y={0} width={120} height={70} fill="#fff" />
<Circle x={24} y={35} radius={16} fill="#ff5aa5" />
</Group>
Dragging a group