React DnD拖动外部同名物品未生成新key问题排查求助
问题根因
你第一次拖拽外部组件进入看板时,直接修改了原始的外部组件对象,给它新增了key属性。由于外部组件的component是引用类型,后续再拖拽同一组件时,它已经携带key属性,因此会命中移动逻辑而非新增逻辑。
修复步骤
1. 核心修复:避免修改原始拖拽对象
修改Board组件drop回调中的对象合并逻辑,不要直接修改传入的item,而是创建全新的对象存储到看板状态中:
// 原来的写法(错误:会修改原对象) // const newItem = Object.assign(item, itemKey); // 修复后的写法 const newItem = Object.assign({}, item, itemKey);
将空对象作为Object.assign的第一个参数,就会生成完全独立的新对象,不会污染原始的外部组件对象,后续拖拽同一外部组件时item.key依旧为undefined,会正常触发新增逻辑。
2. 可选优化:增加拖拽来源标识(更稳妥)
仅靠key是否存在判断逻辑有潜在风险,你可以给不同来源的拖拽对象增加标识字段,判断更准确:
修改外部Component组件的useDrag配置:
useDrag( () => ({ type: ItemTypes.COMPONENT, item: { ...component, source: 'external' // 标记为外部来源 }, }), [] )
修改看板内Item组件的useDrag配置:
useDrag( () => ({ type: ItemTypes.COMPONENT, item: { ...component, source: 'internal' // 标记为内部来源 }, collect: (monitor) => ({ isDragging: monitor.isDragging(), }), }), [component.key, left, top] // 修复依赖项:React的key属性不会传递给子组件props,改用component.key )
调整Board组件的drop判断逻辑:
drop: (item) => { console.log(item.name, item.key); if (item.source === 'external') { const { nanoid } = require("nanoid"); const itemKey = { key: nanoid(16) }; const newItem = Object.assign({}, item, itemKey); setComponents((components) => [...components, newItem]); console.log("add"); } else { // 这里补充内部拖拽的移动逻辑即可 console.log("moving"); } }
内容的提问来源于stack exchange,提问作者Tawpik Talat
相关产品推荐
相关产品推荐

