react-beautiful-dnd React 拖拽(Drag and Drop)库

发布于:2025-09-02 ⋅ 阅读:(22) ⋅ 点赞:(0)

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) => (
    <div
      ref={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) => (
                  <div
                    ref={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)、任务卡片拖动、简单的拖放交互
核心概念 DragDropContextDroppableDraggable
优点 动画优美、API 简洁、上手容易、专精于列表/看板拖拽
缺点 不支持自由拖放(如画布任意位置)、功能相对专注
推荐程度 ⭐⭐⭐⭐⭐ 如果你做的是任务排序、看板拖动,强烈推荐!

✅ 一句话总结

​**react-beautiful-dnd 是 React 生态中最流行、最优雅的拖拽排序库,特别适合实现​ ​列表拖动、看板任务管理、卡片排序等交互,具有流畅动画和简单易用的 API,是开发类似 Trello 功能的首选方案。​**​