react-beautiful-dnd React 拖拽(Drag and Drop)库
react-beautiful-dnd
是一个非常流行且功能强大的 React 拖拽(Drag and Drop)库,由 Atlassian(Jira 和 Trello 的开发公司)开发和维护,专门用于在 React 应用中实现美观、流畅、高度可定制的拖拽交互体验,尤其适合用于:
- 列表/看板拖拽排序
- 看板(Kanban)式任务管理(如 Trello)
- 可拖拽的卡片、列表、表格行
- 任何需要“拖放”交互的 UI 场景
✅ 一、react-beautiful-dnd 是什么?
**react-beautiful-dnd
是一个专注于 React 的、高性能、优雅的拖拽库**,它让你可以:
轻松地为列表中的任意元素(如卡片、div、列表项)添加 拖动和放置(drag & drop)功能,并且提供 丝滑的动画、灵活的 API 和强大的扩展能力。
🔗 官方文档:
👉 https://github.com/atlassian/react-beautiful-dnd
👉 在线体验: https://react-beautiful-dnd.netlify.app/
✅ 二、主要特性
特性 | 说明 |
---|---|
✅ 专为 React 设计 | 与 React 紧密集成,使用 React 组件和 Hooks 风格 |
✅ 流畅 & 美观的动画 | 拖动时有平滑的动画效果,体验接近原生 |
✅ 支持复杂布局 | 不仅支持简单列表,还支持多列看板(如 Trello)、嵌套拖拽等 |
✅ 高度可定制 | 样式、行为、拖动手柄、拖动区域都可灵活控制 |
✅ 无依赖外部动画库 | 自带优美动画,无需额外引入如 framer-motion 等 |
✅ 支持触摸设备 | 在移动端也可以正常使用(但主要优化在桌面端) |
❌ 仅支持垂直/水平拖拽(目前) | 不支持自由方向的拖放(比如画布任意位置拖放,这种需求用 react-dnd 或 dnd-kit 更合适) |
✅ 三、核心概念(重要!)
在使用 react-beautiful-dnd
之前,需要了解它的一些核心概念和术语:
1. DragDropContext
👉 最外层的容器,用来包裹整个可拖拽的区域,是拖放功能的入口。
<DragDropContext onDragEnd={onDragEnd}>{/* 你的可拖拽列表/看板 */}
</DragDropContext>
- 你必须提供一个
onDragEnd(result)
回调,用来处理拖动结束后的逻辑(比如更新数据顺序)。
2. Droppable
👉 表示一个可放置(drop)区域,比如一个列表、一列看板。
<Droppable droppableId="list-1">{(provided, snapshot) => (<div{...provided.droppableProps}ref={provided.innerRef}style={/* 你的样式,可以加上 snapshot.isDraggingOver 样式 */}>{/* 可拖动的项目列表 */}{items.map((item, index) => (<Draggable key={item.id} draggableId={item.id} index={index}>{/* ... */}</Draggable>))}{provided.placeholder} {/* 必须!用来占位,保持拖动后布局不乱 */}</div>)}
</Droppable>
droppableId
: 唯一标识这个放置区域provided.innerRef
: 必须附加到你的 DOM 容器上provided.droppableProps
: 一些拖放需要的属性,也要附加到容器provided.placeholder
: 拖动时用来撑开位置的占位符,不要忘记渲染它
3. Draggable
👉 表示一个可拖动的元素,比如列表中的一项、看板中的一张卡片。
<Draggable draggableId={item.id} index={index}>{(provided, snapshot) => (<divref={provided.innerRef}{...provided.draggableProps}{...provided.dragHandleProps}style={{/* 你的样式 */...provided.draggableProps.style, // 拖动时的偏移样式}}>{item.content}</div>)}
</Draggable>
draggableId
: 唯一标识这个拖动项index
: 当前项在列表中的索引(用于排序)provided.innerRef
: 必须绑定到你拖动的 DOM 元素上provided.draggableProps
: 拖动相关的属性(比如 transform 样式)provided.dragHandleProps
: 拖动手柄的属性(比如鼠标抓取区域,可只放在标题栏上)
🎯 你可以把
dragHandleProps
只放在某个子元素上(如标题栏),这样只有点击那里才能拖动,而不是整个卡片。
✅ 四、简单示例:可拖拽排序的列表
下面是一个 最基础的拖拽排序列表 的例子 👇:
1. 安装
npm install react-beautiful-dnd
2. 代码示例
import React, { useState } from 'react';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';// 初始数据
const initialItems = [{ id: '1', content: '任务 1' },{ id: '2', content: '任务 2' },{ id: '3', content: '任务 3' },
];export default function DragList() {const [items, setItems] = useState(initialItems);// 拖动结束处理const onDragEnd = (result) => {if (!result.destination) return; // 拖到了外面,不做处理const newItems = Array.from(items);const [reorderedItem] = newItems.splice(result.source.index, 1);newItems.splice(result.destination.index, 0, reorderedItem);setItems(newItems);};return (<DragDropContext onDragEnd={onDragEnd}><Droppable droppableId="droppable-list">{(provided, snapshot) => (<div{...provided.droppableProps}ref={provided.innerRef}style={{padding: 8,width: 250,background: snapshot.isDraggingOver ? '#f0f0f0' : '#ddd',borderRadius: 4,}}>{items.map((item, index) => (<Draggable key={item.id} draggableId={item.id} index={index}>{(provided, snapshot) => (<divref={provided.innerRef}{...provided.draggableProps}{...provided.dragHandleProps}style={{userSelect: 'none',padding: 16,margin: '0 0 8px 0',background: snapshot.isDragging ? '#bee3f8' : '#fff',borderRadius: 4,...provided.draggableProps.style,}}>{item.content}</div>)}</Draggable>))}{provided.placeholder}</div>)}</Droppable></DragDropContext>);
}
✅ 五、适用场景
场景 | 是否适合 | 说明 |
---|---|---|
📋 列表项拖拽排序(如代办事项) | ✅ 非常适合 | 核心使用场景 |
📊 看板(Kanban)拖拽(如 Trello) | ✅ 非常适合 | 多列 + 每列多行 |
🖼️ 画布任意位置拖放 | ❌ 不适合 | 不支持自由拖放定位,推荐 react-dnd 或 dnd-kit |
📱 移动端拖放 | ⚠️ 有限支持 | 基本可用,但主要优化在桌面端 |
🔄 拖放交换位置 / 跨列表移动 | ✅ 支持 | 可以在不同 Droppable 间拖动 |
✅ 六、对比其他拖拽库
库名 | 特点 | 适用场景 | 对比 |
---|---|---|---|
react-beautiful-dnd | 美观、动画流畅、易用、官方维护(Atlassian) | 列表、看板拖拽排序 | ✅ 推荐用于 Trello-like 看板、任务排序 |
react-dnd | 功能强大、非常灵活、插件化、较复杂 | 自定义拖放逻辑、跨组件拖放 | ⚠️ 学习曲线陡峭,适合高级需求 |
dnd-kit | 现代、轻量、灵活、支持自由拖放 | 新项目推荐,支持复杂交互 | ✅ 推荐用于更自由的拖放需求 |
react-beautiful-dnd | 美观流畅、专为列表/看板设计 | 列表排序、看板任务 | ✅ 最贴合“拖动排序”类需求 |
✅ 如果你要做“列表拖动排序”或“看板任务拖动”,
react-beautiful-dnd
是最简单、最漂亮、最推荐的选择!
✅ **如果你需要更灵活的拖放(比如任意位置放置、跨组件交互),可以考虑
dnd-kit
或react-dnd
**
✅ 七、总结
项目 | 说明 |
---|---|
react-beautiful-dnd 是什么? | 一个由 Atlassian 开发的、专为 React 设计的 拖拽排序/看板库,以流畅动画和易用 API 著称 |
适合什么场景? | 列表排序、看板(如 Trello)、任务卡片拖动、简单的拖放交互 |
核心概念 | DragDropContext 、Droppable 、Draggable |
优点 | 动画优美、API 简洁、上手容易、专精于列表/看板拖拽 |
缺点 | 不支持自由拖放(如画布任意位置)、功能相对专注 |
推荐程度 | ⭐⭐⭐⭐⭐ 如果你做的是任务排序、看板拖动,强烈推荐! |
✅ 一句话总结
**
react-beautiful-dnd
是 React 生态中最流行、最优雅的拖拽排序库,特别适合实现 列表拖动、看板任务管理、卡片排序等交互,具有流畅动画和简单易用的 API,是开发类似 Trello 功能的首选方案。**