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
相关产品推荐
相关产品推荐

