React beautiful dnd两列布局首列拖拽失效,提示无法找到对应id的draggable
核心错误原因
react-beautiful-dnd 强依赖每个 Draggable 元素的 index 参数与它在所属 Droppable 下的实际渲染顺序完全一致,你的代码中存在多处索引、ID 不匹配的问题,直接导致偶发找不到 draggable 的报错。
具体修复步骤
1. 修正index计算逻辑
你当前通过 availableSections.indexOf(visibleAvailableSections[section]) 计算索引,当存在搜索过滤逻辑时,visibleAvailableSections 是原始列表的子集,indexOf 返回的是元素在原始列表中的位置,和当前渲染列表的顺序完全不匹配,这是最直接的报错原因。
直接使用map方法的原生索引参数即可:
// 两列的渲染逻辑都做相同修改 // 原写法 {Object.keys(visibleAvailableSections).map((section) => { return <SectionCard key ={visibleAvailableSections[section]._id} section={ visibleAvailableSections[section] } index={parseInt(availableSections.indexOf(visibleAvailableSections[section])) } /> })} // 修正后写法 {Object.keys(visibleAvailableSections).map((section, index) => { return <SectionCard key={visibleAvailableSections[section]._id.toString()} section={visibleAvailableSections[section]} index={index} /> })}
2. 统一ID类型
你的 _id 看起来是MongoDB的ObjectId类型,第一个列的SectionCard的key没有调用toString(),和Draggable组件的draggableId={section._id.toString()}类型不一致,会导致库内部缓存匹配失败。所有用到_id作为key、draggableId的位置统一调用toString()保证类型一致。
3. 稳定渲染顺序
你用Object.keys(visibleAvailableSections)遍历对象,JS中对象键的返回顺序不保证完全稳定,建议将过滤后的可见列表提前转为数组再渲染,彻底避免顺序错乱:
// 渲染前先转成稳定数组 const visibleAvailableList = Object.values(visibleAvailableSections) const visibleSelectedList = Object.values(visibleSelectedSections) // 渲染时直接遍历数组 {visibleAvailableList.map((section, index) => ( <SectionCard key={section._id.toString()} section={section} index={index} /> ))}
4. React 18兼容处理
如果你的项目使用React 18+且开启了严格模式,react-beautiful-dnd会因为严格模式的双渲染机制出现偶发的内部缓存错误,可暂时移除根组件的<React.StrictMode>包裹,或者改用兼容React 18的维护分支@hello-pangea/dnd,API完全一致不需要修改业务代码。
内容的提问来源于stack exchange,提问作者Steven Bendell

