You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-beautiful-dnd拖拽异常:无法找到ID与非连续索引报错

react-beautiful-dnd拖拽异常问题解决

问题1:首次拖拽后无法再次移动项,报错 Unable to find draggable with id: XXX

原因

  • 拖拽排序时直接修改原数据源数组,未做不可变更新,导致React状态更新不彻底,组件实例与内部追踪的draggable id不匹配。
  • <Draggable>子元素的key使用数组索引而非项的唯一标识,排序后索引变化,React复用错误的组件实例。

解决方法

  • 用不可变操作更新数据源:排序时通过Array.from()、扩展运算符[...arr]或slice()生成新数组,禁止直接用splice()修改原数组。
  • 绑定唯一稳定的key:给<Draggable>的子元素绑定项的唯一id(如item.id),不要用数组索引作为key。

问题2:拖拽其他项时UI错乱,报错 Detected non-consecutive <Draggable /> indexes.(This can cause unexpected bugs) 0, [🔥2], 3, 4, 5

原因

<Draggable>的index属性不是连续的0、1、2...序列,中间出现索引断层,通常是过滤数据源后未重新生成连续索引,或排序后索引未同步更新。

解决方法

  • 确保索引连续:遍历数据源渲染<Draggable>时,直接使用map的第二个参数(当前项在数组中的索引)作为index值,保证索引从0开始连续递增。
  • 过滤后重置索引:如果有数据过滤操作,过滤后的新数组必须重新生成连续索引,不要保留原数组的旧索引。

正确代码示例

拖拽结束处理函数

const handleDragEnd = (result) => {
  if (!result.destination) return;

  // 不可变方式重新排序数组
  const newItems = [...items];
  const [movedItem] = newItems.splice(result.source.index, 1);
  newItems.splice(result.destination.index, 0, movedItem);

  setItems(newItems);
};

渲染部分

<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}
              >
                {item.name}
              </div>
            )}
          </Draggable>
        ))}
        {provided.placeholder}
      </div>
    )}
  </Droppable>
</DragDropContext>

内容的提问来源于stack exchange,提问作者Juan Menendez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 03:20:35