react原生实现拖拽排序
使用 react-dnd 实现拖拽排序
react-dnd 是一个流行的 React 拖拽库,基于 HTML5 拖拽 API 实现。安装依赖:
npm install react-dnd react-dnd-html5-backend
创建可拖拽项和放置区域组件:
import { useDrag, useDrop } from 'react-dnd';
const DraggableItem = ({ id, text, index, moveItem }) => {
const [{ isDragging }, drag] = useDrag({
type: 'ITEM',
item: { id, index },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
const [, drop] = useDrop({
accept: 'ITEM',
hover: (draggedItem) => {
if (draggedItem.index !== index) {
moveItem(draggedItem.index, index);
draggedItem.index = index;
}
},
});
return (
<div
ref={(node) => drag(drop(node))}
style={{
opacity: isDragging ? 0.5 : 1,
padding: '8px',
margin: '4px',
border: '1px solid #ddd',
}}
>
{text}
</div>
);
};
实现排序容器:

import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
const SortableList = ({ items, setItems }) => {
const moveItem = (fromIndex, toIndex) => {
const newItems = [...items];
const [movedItem] = newItems.splice(fromIndex, 1);
newItems.splice(toIndex, 0, movedItem);
setItems(newItems);
};
return (
<DndProvider backend={HTML5Backend}>
{items.map((item, index) => (
<DraggableItem
key={item.id}
id={item.id}
text={item.text}
index={index}
moveItem={moveItem}
/>
))}
</DndProvider>
);
};
使用 react-beautiful-dnd 实现拖拽排序
react-beautiful-dnd 是专为列表排序优化的拖拽库。安装依赖:
npm install react-beautiful-dnd
实现可排序列表:

import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
const SortableList = ({ items, setItems }) => {
const handleDragEnd = (result) => {
if (!result.destination) return;
const newItems = [...items];
const [reorderedItem] = newItems.splice(result.source.index, 1);
newItems.splice(result.destination.index, 0, reorderedItem);
setItems(newItems);
};
return (
<DragDropContext onDragEnd={handleDragEnd}>
<Droppable droppableId="list">
{(provided) => (
<div {...provided.droppableProps} ref={provided.innerRef}>
{items.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={{
padding: '8px',
margin: '4px',
border: '1px solid #ddd',
...provided.draggableProps.style,
}}
>
{item.text}
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
);
};
自定义实现拖拽排序
不依赖第三方库的基础实现:
const SortableList = ({ items, setItems }) => {
const [draggedItem, setDraggedItem] = useState(null);
const handleDragStart = (index) => {
setDraggedItem(index);
};
const handleDragOver = (index) => {
if (draggedItem === null || draggedItem === index) return;
const newItems = [...items];
const [movedItem] = newItems.splice(draggedItem, 1);
newItems.splice(index, 0, movedItem);
setItems(newItems);
setDraggedItem(index);
};
return (
<div>
{items.map((item, index) => (
<div
key={item.id}
draggable
onDragStart={() => handleDragStart(index)}
onDragOver={() => handleDragOver(index)}
style={{
padding: '8px',
margin: '4px',
border: '1px solid #ddd',
cursor: 'move',
}}
>
{item.text}
</div>
))}
</div>
);
};
性能优化建议
对于大型列表,应优化渲染性能:
- 为列表项添加稳定的 key
- 使用 React.memo 包装列表项组件
- 避免在拖动过程中不必要的重新渲染
- 考虑虚拟滚动技术处理超长列表
移动端适配注意事项:
- 添加 touch 事件处理
- 调整拖拽灵敏度
- 考虑使用 react-dnd-touch-backend 作为后端





