React DnD索引变更后拖拽失效问题求助
React DnD拖拽排序异常:元素索引变更后无法再次拖拽
我尝试用React DnD实现数组moduleList中元素的排序功能,但出现异常:元素仅能被拖拽到索引发生变更一次,之后便无法再响应拖拽操作。具体表现:
- 将索引0的元素拖拽到索引1和2之间,前两个元素成功交换位置及索引,但之后这两个元素不再响应拖拽;
- 索引2的元素可继续拖拽,但放置到新位置后也会失效;
- 若将索引0的元素直接拖拽到最后位置,所有元素索引变更后均无法拖拽。
相关简化代码如下:
const App = ({ modules, status }) => { const [moduleList, setModuleList] = useState(modules); const dropModule = (input) => { const { index, module } = input; if (index === null) return; let newModules = [...moduleList] if (module.key) { let toDeleteIndex = moduleList.findIndex(mod => { return mod.key === module.key; }) if (toDeleteIndex < 0) return; newModules.splice(toDeleteIndex, 1); newModules.splice(index, 0, module) } else { newModules.splice(index, 0, { type: "standard_module", key: Math.random() }) } console.log({newModules}) setModuleList(newModules) } const renderModule = (module, index) => { const dropRef = useRef(null); const dragRef = useRef(null); const [{ isOver }, drop] = useDrop({ accept: "MODULE", drop: () => ({module, index}), collect: monitor => ({ isOver: !!monitor.isOver() }) }) const [{ isDragging }, drag, dragPreview] = useDrag({ type: "MODULE", item: module, end(item, monitor) { const dropResult = monitor.getDropResult() if (dropResult) dropModule({ module: item, index: dropResult?.index }); }, collect: monitor => ({ isDragging: !!monitor.isDragging(), }) }) dragPreview(drop(dropRef)) drag(dragRef) return ( <div ref={dropRef} key={`${index}-${module.key}`}> <div ref={dragRef} className="module-menu"><i>expand</i>{index}</div> ...module element (code not relevant, I don't think) </div> ) } return ( <article> { moduleList.map((module, x) => { return renderModule(module, x) }) } </article> ) }
我认为代码逻辑和其他示例一致,但找不到问题根源。另外,给module添加key属性是为了解决React无法识别元素位置交换的问题——之前用索引作为key时,React只会在数组末尾渲染新元素,唯一key能让React识别元素位置变更,不确定这是否与当前问题有关。
内容的提问来源于stack exchange,提问作者JoshuaM
相关产品推荐
相关产品推荐

