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

使用react-beautiful-dnd报错:无法找到上下文‘0’中的拖拽句柄

解决react-beautiful-dnd报错‘Unable to find any drag handles in the context "0"’的常见原因

这个报错本质是react-beautiful-dnd找不到合法的拖拽触发元素,或者拖拽组件的层级结构不符合要求,结合你提到的三个组件,重点排查以下几点:

  • 拖拽组件层级嵌套错误
    必须严格遵循 DragDropContext → Droppable → Draggable 的嵌套顺序:

    • RandomizerPage里必须用 <DragDropContext> 包裹整个拖拽相关区域,且必须传入 onDragEnd 回调(哪怕暂时为空);
    • PlayerList里的 <Droppable> 必须放在 DragDropContext 内部;
    • 每个PlayerCard对应的 <Draggable> 必须放在 <Droppable> 的渲染回调内部,不能脱离这个上下文。
  • Draggable未绑定拖拽手柄
    PlayerCard作为Draggable的子组件,必须有一个元素绑定 provided.dragHandleProps —— 这就是拖拽时的触发区域。如果你的PlayerCard里没加这个属性,或者绑定的元素不在正确的层级(比如被其他阻止事件的元素覆盖),就会报这个错。
    正确的做法是在PlayerCard的某个可点击区域(比如卡片标题)展开这个props:

    // PlayerCard.tsx 示例
    <div {...provided.dragHandleProps}>
      {player.name}
    </div>
    
  • Draggable的index属性重复或无效
    渲染Draggable时,index 必须是当前项在列表中的唯一索引,不能用固定值或者重复的id。比如在PlayerList的map循环里,必须用map的第二个参数作为index,而不是随便写死的数字。

  • 未正确传递provided参数
    Draggable的渲染回调会返回 provided 对象,里面包含 draggableProps、dragHandleProps、innerRef 三个关键属性,必须完整传递给PlayerCard对应的元素:

    • provided.innerRef 要绑定到Draggable的最外层元素;
    • provided.draggableProps 要绑定到最外层元素;
    • provided.dragHandleProps 绑定到拖拽触发元素。

举个标准的结构示例:

// RandomizerPage.tsx
import { DragDropContext } from 'react-beautiful-dnd';

export default function RandomizerPage() {
  const handleDragEnd = () => {}; // 必须定义,哪怕空实现

  return (
    <DragDropContext onDragEnd={handleDragEnd}>
      <PlayerList players={yourPlayerList} />
    </DragDropContext>
  );
}

// PlayerList.tsx
import { Droppable, Draggable } from 'react-beautiful-dnd';

export default function PlayerList({ players }) {
  return (
    <Droppable droppableId="player-list">
      {(provided) => (
        <div
          {...provided.droppableProps}
          ref={provided.innerRef}
        >
          {players.map((player, idx) => (
            <Draggable key={player.id} draggableId={player.id} index={idx}>
              {(provided) => (
                <PlayerCard player={player} provided={provided} />
              )}
            </Draggable>
          ))}
          {provided.placeholder} {/* 必须加这个占位符,防止布局跳动 */}
        </div>
      )}
    </Droppable>
  );
}

// PlayerCard.tsx
export default function PlayerCard({ player, provided }) {
  return (
    <div
      ref={provided.innerRef}
      {...provided.draggableProps}
      className="player-card"
    >
      {/* 这个div就是拖拽手柄 */}
      <div {...provided.dragHandleProps} className="drag-handle">
        {player.name}
      </div>
      <p>{player.position}</p>
    </div>
  );
}

对照你的代码检查以上几点,基本就能定位问题。

内容的提问来源于stack exchange,提问作者luckyme-

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:10:53