react实现div的拖拽
实现拖拽的基本思路
在React中实现拖拽功能,通常利用HTML5的Drag and Drop API或第三方库(如react-dnd、react-beautiful-dnd)。以下是两种方法的实现示例。
使用HTML5 Drag and Drop API
HTML5原生API适合简单场景,需通过事件监听实现拖拽逻辑。
定义拖拽元素
为可拖拽元素添加draggable属性,并监听onDragStart事件:

<div
draggable
onDragStart={(e) => {
e.dataTransfer.setData("text/plain", "drag-item-id"); // 传递数据
}}
>
拖拽元素
</div>
定义放置区域
放置区域需监听onDragOver(阻止默认行为)和onDrop事件:
<div
onDragOver={(e) => e.preventDefault()} // 必须阻止默认行为
onDrop={(e) => {
e.preventDefault();
const itemId = e.dataTransfer.getData("text/plain");
console.log("放置元素ID:", itemId);
}}
>
放置区域
</div>
完整组件示例

import React from "react";
function DragDemo() {
return (
<div>
<div
draggable
onDragStart={(e) => e.dataTransfer.setData("text/plain", "item-1")}
style={{ padding: "10px", background: "lightblue" }}
>
拖拽我
</div>
<div
onDragOver={(e) => e.preventDefault()}
onDrop={(e) => {
e.preventDefault();
alert(`接收到数据: ${e.dataTransfer.getData("text/plain")}`);
}}
style={{ padding: "20px", background: "lightgray", marginTop: "20px" }}
>
放置区域
</div>
</div>
);
}
使用第三方库(react-dnd)
对于复杂场景(如排序列表),推荐使用react-dnd库。
安装依赖
npm install react-dnd react-dnd-html5-backend
实现拖拽排序
import React from "react";
import { DndProvider, useDrag, useDrop } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
const DraggableItem = ({ id, text, moveItem }) => {
const [{ isDragging }, drag] = useDrag({
type: "ITEM",
item: { id },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
const [, drop] = useDrop({
accept: "ITEM",
hover: (draggedItem) => {
if (draggedItem.id !== id) {
moveItem(draggedItem.id, id);
}
},
});
return (
<div
ref={(node) => drag(drop(node))}
style={{
opacity: isDragging ? 0.5 : 1,
padding: "8px",
margin: "4px",
background: "lightgreen",
cursor: "move",
}}
>
{text}
</div>
);
};
function DragList() {
const [items, setItems] = React.useState([
{ id: 1, text: "Item 1" },
{ id: 2, text: "Item 2" },
{ id: 3, text: "Item 3" },
]);
const moveItem = (fromId, toId) => {
const fromIndex = items.findIndex((item) => item.id === fromId);
const toIndex = items.findIndex((item) => item.id === toId);
const newItems = [...items];
const [movedItem] = newItems.splice(fromIndex, 1);
newItems.splice(toIndex, 0, movedItem);
setItems(newItems);
};
return (
<DndProvider backend={HTML5Backend}>
{items.map((item) => (
<DraggableItem
key={item.id}
id={item.id}
text={item.text}
moveItem={moveItem}
/>
))}
</DndProvider>
);
}
关键注意事项
- 性能优化:频繁拖拽时,避免直接修改状态,可使用防抖或不可变数据。
- 跨浏览器兼容性:HTML5 API在移动端支持有限,推荐使用库(如
react-dnd)。 - 无障碍支持:为拖拽元素添加
aria-grabbed等ARIA属性。
通过上述方法,可灵活实现React中的拖拽功能,从简单到复杂场景均可覆盖。






