在react实现拖动
实现拖动的核心方法
使用HTML5的Drag and Drop API结合React状态管理是最基础的实现方式。需要处理draggable属性、onDragStart和onDrop等事件。
function DraggableItem({ id, children }) {
const handleDragStart = (e) => {
e.dataTransfer.setData('text/plain', id);
};
return (
<div
draggable
onDragStart={handleDragStart}
style={{ cursor: 'move' }}
>
{children}
</div>
);
}
使用第三方库react-dnd
react-dnd提供了更高级的抽象层,适合复杂场景。安装后通过useDrag和useDrophooks实现。

npm install react-dnd react-dnd-html5-backend
import { useDrag, useDrop } from 'react-dnd';
function DraggableBox({ id }) {
const [{ isDragging }, drag] = useDrag(() => ({
type: 'BOX',
item: { id },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
}));
return (
<div
ref={drag}
style={{
opacity: isDragging ? 0.5 : 1,
cursor: 'move',
}}
>
Drag me
</div>
);
}
实现可排序列表
结合react-dnd的useDrop实现列表排序功能,需要维护列表状态。
function SortableList({ items, onMove }) {
const [, drop] = useDrop(() => ({
accept: 'ITEM',
drop: (item) => onMove(item.id),
}));
return (
<div ref={drop}>
{items.map((item) => (
<DraggableItem key={item.id} id={item.id} />
))}
</div>
);
}
触摸设备支持
针对移动端需要添加触摸事件处理,或使用支持触摸的库如react-beautiful-dnd。

const handleTouchStart = (e) => {
// 记录初始位置
};
const handleTouchMove = (e) => {
// 计算位移并更新元素位置
};
性能优化技巧
对于大量可拖动元素,采用虚拟滚动技术。react-window或react-virtualized可减少DOM节点数量。
import { FixedSizeList as List } from 'react-window';
function Row({ index, style }) {
return (
<div style={style}>
<DraggableItem id={index} />
</div>
);
}
function BigList() {
return (
<List
height={500}
itemCount={1000}
itemSize={50}
>
{Row}
</List>
);
}
自定义拖动预览
通过setDragImage修改拖动时的预览图像,提升用户体验。
const handleDragStart = (e) => {
const img = new Image();
img.src = 'preview.png';
e.dataTransfer.setDragImage(img, 10, 10);
};






