AI, ML, and networking — applied and examined.
一代神库陨落,Atlassian亲手杀死了React最美拖拽库
一代神库陨落,Atlassian亲手杀死了React最美拖拽库

一代神库陨落,Atlassian亲手杀死了React最美拖拽库

做前端开发的兄弟们,每天最怕听到的一句话是什么?

不是“需求变了”,也不是“后端接口500”,而是产品经理兴致勃勃地跑过来说:“这个列表,我要能拖拽排序,还要丝滑,要像Trello那样,对了,手机上也要能用!

此时你的内心大概率是崩溃的。原生的 HTML5 Drag and Drop API 简直就是一场灾难,不仅 API 设计得像上个世纪的产物,各家浏览器的兼容性更是让你想砸键盘。

于是,你打开了 GitHub,寻找那个传说中的救世主——react-beautiful-dnd(简称 rbd)。

但今天这篇文章,不是来给你安利它的,而是来祭奠它的。

没错,这个拥有 30k+ Star,曾经是 React 生态中拖拽交互“颜值天花板”的项目,已经被 Atlassian 官方归档(Archived)了

但这并不妨碍我们最后一次“验尸”,看看它到底凭什么曾经统治了我们的看板。

核心亮点:为什么它曾是唯一的真神?

react-beautiful-dnd 出现之前,React 社区的拖拽库大多是“能用就行”。但 RBD 的出现,直接把标准拉到了“艺术品”的层级。

1. 物理引擎般的“自然交互”

很多拖拽库的实现非常生硬:你把一个元素拖起来,下面的元素瞬间闪现填补空位,视觉上非常突兀。

RBD 最强的地方在于它的动画设计。当你拖动一个 Item 时,列表中的其他元素会像有磁力一样,平滑地、带有物理惯性地让出位置。这种“让路”的动画(Animate out of the way),让用户感觉到他操作的不是冷冰冰的 DOM,而是有实体的卡片。

更绝的是,它不需要你写一行 CSS Transition,开箱即送。

react beautiful dnd example

2. 真正的无障碍(Accessibility)之王

现在的开源项目,不做 a11y(无障碍)都不好意思出来混。但 RBD 是真的做到了极致。

大多数拖拽库对键盘支持是 0。RBD 允许用户使用键盘聚焦某个卡片,按空格键“提起”,再用方向键移动,最后按空格“放下”。它甚至内置了针对屏幕阅读器的英文提示音。对于那些无法使用鼠标的用户,RBD 依然提供了完整的拖拽体验。这点上,很多竞品至今难以望其项背。

3. 虚拟列表支持:千万级数据也不卡

搞拖拽最怕什么?卡顿。如果你有 10,000 个待办事项,普通的拖拽库直接能把浏览器搞崩。

RBD 在 README 里极其嚣张地写着:Support for virtual lists – unlocking 10,000 items @ 60fps。它通过精妙的计算和对可视区域的判断,完美兼容了虚拟滚动技术。这在当年,简直就是性能优化的黑魔法。


竞品对比:后 RBD 时代的群雄逐鹿

既然 react-beautiful-dnd 已经官方宣布由于维护成本过高而停止维护,那我们现在该用什么?来看看现在的战局。

1. 官方指定继承人:Pragmatic Drag and Drop

Atlassian 在废弃 RBD 的同时,推出了继任者 Pragmatic Drag and Drop
* 对比 RBD:RBD 是高度封装的,给你什么你就得用什么(Opnionated);而 Pragmatic 更底层、更灵活,不仅支持 List,还支持文件上传、Grid 等任意布局。
* 槽点:RBD 的 API 是真的简单(声明式),Pragmatic 的 API 更加底层,上手难度直线上升。如果你只是想做一个简单的看板,用这个有点“大炮打蚊子”。

2. 民间复活版:@hello-pangea/dnd

这是目前社区最推荐的无痛替代方案
* 背景:由于 RBD 长期不修 Bug(尤其是 React 18 的 Strict Mode 兼容性问题),社区大佬忍不住了,直接 Fork 了一个版本叫 hello-pangea/dnd
* 优势它就是 RBD 的克隆体。你只需要把 import { DragDropContext } ... from 'react-beautiful-dnd' 改成 from '@hello-pangea/dnd',代码一行都不用动,Bug 全修好了,React 18 也支持了。
* 评价:如果你还在维护用 RBD 写的旧项目,请立刻无脑切到这个库

3. 老牌劲敌:React DnD

  • 对比react-dnd 一直是 RBD 的死对头。RBD 专注于“列表”,而 react-dnd 是一套通用的拖拽原语。
  • 劣势:配置极其繁琐,写一个简单的排序需要写大量的样板代码。如果你不需要搞什么骚操作,只是简单的列表排序,用 react-dnd 简直是自虐。

部署与使用:最后的挽歌

虽然它归档了,但它的 API 设计之优雅,依然值得我们学习。它的核心概念只有三个,简直是声明式编程的教科书。

先看看这极简的架构图:

API diagram

核心三剑客

  1. DragDropContext: 包裹整个拖拽区域,处理 onDragEnd 事件。
  2. Droppable: 定义哪些区域可以“接收”被拖拽的元素(比如“待办”列、“完成”列)。
  3. Draggable: 定义哪些元素可以被“抓起来”。

极速上手代码

import React from 'react';
// ⚠️ 警告:新项目建议使用 @hello-pangea/dnd 替代下方引用
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

const list = [{id: '1', content: '点个赞'}, {id: '2', content: '关注我'}];

function App() {
  const onDragEnd = (result) => {
    // 这里处理数组排序逻辑,比如使用 result.source.index 和 result.destination.index
    console.log('拖拽结束,快去更新你的 State');
  };

  return (
    <DragDropContext onDragEnd={onDragEnd}>
      <Droppable droppableId="droppable">
        {(provided) => (
          <div
            {...provided.droppableProps}
            ref={provided.innerRef}
          >
            {list.map((item, index) => (
              <Draggable key={item.id} draggableId={item.id} index={index}>
                {(provided) => (
                  <div
                    ref={provided.innerRef}
                    {...provided.draggableProps}
                    {...provided.dragHandleProps}
                    style={{ 
                        padding: 16, 
                        margin: '0 0 8px 0', 
                        background: '#fff',
                        ...provided.draggableProps.style 
                    }}
                  >
                    {item.content}
                  </div>
                )}
              </Draggable>
            ))}
            {provided.placeholder} {/* 占位符,防止高度塌陷 */}
          </div>
        )}
      </Droppable>
    </DragDropContext>
  );
}

这段代码最迷人的地方在于 Function as Child (Render Props) 模式的使用。虽然现在 Hooks 流行了,但在当时,这种将 DOM refprops 通过函数参数透传出来的设计,极大地保证了灵活性——它不增加额外的 DOM 节点,完全尊重你的布局。

结语

react-beautiful-dnd 的归档,标志着一个时代的结束。它教会了我们:拖拽不仅仅是功能的实现,更是物理手感和视觉反馈的艺术。

如果你是维护旧项目,请出门左转找 @hello-pangea/dnd;如果你是新项目,可以挑战一下 Atlassian 的新宠 Pragmatic drag and drop

至于 RBD,就让它留在我们的 package.json 历史记录里,成为一座丰碑吧。

项目地址: https://github.com/atlassian/react-beautiful-dnd

Leave a Reply

Your email address will not be published. Required fields are marked *