react dnd如何使用
React DnD 基础用法
React DnD 是一个用于实现拖放功能的 React 库。以下是一个基本的使用示例:
安装 React DnD 和 HTML5 后端:
npm install react-dnd react-dnd-html5-backend
创建一个可拖动的组件:
import { useDrag } from 'react-dnd';
function DraggableItem({ id, text }) {
const [{ isDragging }, drag] = useDrag(() => ({
type: 'ITEM',
item: { id },
collect: (monitor) => ({
isDragging: !!monitor.isDragging(),
}),
}));
return (
<div
ref={drag}
style={{
opacity: isDragging ? 0.5 : 1,
cursor: 'move',
}}
>
{text}
</div>
);
}
创建一个可放置的区域:
import { useDrop } from 'react-dnd';
function DropZone({ onDrop }) {
const [{ isOver }, drop] = useDrop(() => ({
accept: 'ITEM',
drop: (item) => onDrop(item.id),
collect: (monitor) => ({
isOver: !!monitor.isOver(),
}),
}));
return (
<div
ref={drop}
style={{
backgroundColor: isOver ? 'lightblue' : 'white',
padding: '20px',
border: '1px dashed gray',
}}
>
放置区域
</div>
);
}
使用 DnD 提供者
在应用顶层设置 DnD 提供者:

import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
function App() {
const [items, setItems] = useState([
{ id: 1, text: '项目1' },
{ id: 2, text: '项目2' },
]);
const handleDrop = (id) => {
console.log(`项目 ${id} 被放置`);
};
return (
<DndProvider backend={HTML5Backend}>
<div>
{items.map((item) => (
<DraggableItem key={item.id} id={item.id} text={item.text} />
))}
<DropZone onDrop={handleDrop} />
</div>
</DndProvider>
);
}
自定义拖拽预览
可以创建自定义的拖拽预览:
import { DragPreviewImage, useDrag } from 'react-dnd';
function CustomDragItem({ id, text }) {
const [{ isDragging }, drag, preview] = useDrag(() => ({
type: 'ITEM',
item: { id },
}));
return (
<>
<DragPreviewImage connect={preview} src="path/to/image.png" />
<div ref={drag} style={{ opacity: isDragging ? 0.5 : 1 }}>
{text}
</div>
</>
);
}
处理复杂数据类型
当需要拖拽复杂数据时:
const [{ isDragging }, drag] = useDrag(() => ({
type: 'COMPLEX_ITEM',
item: {
id: 123,
data: {
name: '示例',
value: 42,
},
},
}));
触摸设备支持
对于触摸设备,需要使用触摸后端:

npm install react-dnd-touch-backend
然后修改提供者:
import { TouchBackend } from 'react-dnd-touch-backend';
function App() {
return (
<DndProvider backend={TouchBackend} options={{ enableMouseEvents: true }}>
{/* 应用内容 */}
</DndProvider>
);
}
性能优化
对于大量可拖拽项目,使用 memoization 优化性能:
const DraggableItem = React.memo(function DraggableItem({ id, text }) {
// 拖拽逻辑
});
类型定义
使用 TypeScript 时定义拖拽项类型:
interface DragItem {
id: number;
type: string;
}
const [{ isDragging }, drag] = useDrag<DragItem, void, { isDragging: boolean }>(() => ({
type: 'ITEM',
item: { id: 1, type: 'EXAMPLE' },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
}));






