Data payloads
Both useDraggable
and useDroppable
hooks accept a data
prop that can be used to attach data to the draggable or droppable component.
This data can be either a plain object or a reanimated shared value. If a plain object is passed, it will be automatically wrapped as a shared value.
Directly using a shared value
// src/App.tsx
import { DndProvider, DndProviderProps, Draggable, Droppable } from "@mgcrea/react-native-dnd";
import type { FunctionComponent } from "react";
import { SafeAreaView, StyleSheet, Text } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
export const App: FunctionComponent = () => {
const dynamicData = useSharedValue({ count: 0 });
const handleDragEnd: DndProviderProps["onDragEnd"] = ({ active, over }) => {
"worklet";
if (over) {
console.log(`Current count is ${active.data.value.count}`);
dynamicData.value = { ...dynamicData.value, count: dynamicData.value.count + 1 };
}
};
return (
<SafeAreaView>
<GestureHandlerRootView>
<DndProvider onBegin={handleBegin} onFinalize={handleFinalize} onDragEnd={handleDragEnd}>
<Droppable id="drop" style={styles.box}>
<Text>DROP</Text>
</Droppable>
<Draggable id="drag" data={dynamicData} style={styles.box}>
<Text>DRAG</Text>
</Draggable>
</DndProvider>
</GestureHandlerRootView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
box: {
margin: 24,
padding: 24,
height: 128,
width: 128,
justifyContent: "center",
alignItems: "center",
backgroundColor: "darkseagreen",
},
});
Using a plain object
// src/App.tsx
import { DndProvider, DndProviderProps, Draggable, Droppable } from "@mgcrea/react-native-dnd";
import type { FunctionComponent } from "react";
import { SafeAreaView, StyleSheet, Text } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
export const App: FunctionComponent = () => {
const [count, setCount] = useState(0);
const onDragEnd = () => {
setCount((count) => count + 1);
};
const handleDragEnd: DndProviderProps["onDragEnd"] = ({ active, over }) => {
"worklet";
if (over) {
console.log(`Current count is ${active.data.value.count}`);
runOnJS(onDragEnd)();
}
};
return (
<SafeAreaView>
<GestureHandlerRootView>
<DndProvider onBegin={handleBegin} onFinalize={handleFinalize} onDragEnd={handleDragEnd}>
<Droppable id="drop" style={styles.box}>
<Text>DROP</Text>
</Droppable>
<Draggable id="drag" data={{ count }} style={styles.box}>
<Text>DRAG</Text>
</Draggable>
</DndProvider>
</GestureHandlerRootView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
box: {
margin: 24,
padding: 24,
height: 128,
width: 128,
justifyContent: "center",
alignItems: "center",
backgroundColor: "darkseagreen",
},
});