我正在使用react-dnd。我想在使用可拖动对象后将其删除。我以react-dnd多类型示例为例,并在拖放时添加了删除。
当前行为: 1.拖动香蕉,右上方的垃圾箱将突出显示 2.将瓶子拖到左侧的任一垃圾桶中 3.再次拖动香蕉,现在突出显示了左侧的两个垃圾箱
预期的行为: 1.将瓶子拖到左侧的任一垃圾桶中 2.拖动香蕉,右上角应突出显示
这是怎么回事,我该如何解决?
https://codesandbox.io/s/pensive-wildflower-q2oxo?file=/src/Dustbin.jsx
答案 0 :(得分:1)
您正在使用数组索引作为框的键并进行删除。处理项目删除操作时,请勿特别将索引用作键。而是,为Box保留唯一的ID。还要正确更新包装盒的状态。
代码段
const Container = () => {
const [dustbins, setDustbins] = useState([
{ accepts: [ItemTypes.GLASS], lastDroppedItem: null },
{ accepts: [ItemTypes.FOOD], lastDroppedItem: null },
{
accepts: [ItemTypes.PAPER, ItemTypes.GLASS, NativeTypes.URL],
lastDroppedItem: null
},
{ accepts: [ItemTypes.PAPER, NativeTypes.FILE], lastDroppedItem: null }
]);
const [boxes, setBoxes] = useState([
{ id: 1, name: "Bottle", type: ItemTypes.GLASS },
{ id: 2, name: "Banana", type: ItemTypes.FOOD },
{ id: 3, name: "Magazine", type: ItemTypes.PAPER }
]);
const [droppedBoxNames, setDroppedBoxNames] = useState([]);
function isDropped(boxName) {
return droppedBoxNames.indexOf(boxName) > -1;
}
const handleDrop = useCallback(
(index, item, id) => {
const { name } = item;
setDroppedBoxNames(prev => [...prev, name]);
// setDroppedBoxNames(
// update(droppedBoxNames, name ? { $push: [name] } : { $push: [] })
// );
setBoxes(prev => prev.filter(x => x.id !== id));
// setBoxes(update(boxes, { $splice: [[item.id, 1]] }));
setDustbins(
update(dustbins, {
[index]: {
lastDroppedItem: {
$set: item
}
}
})
);
},
[droppedBoxNames, boxes, dustbins]
);
return (
<div>
<div style={{ overflow: "hidden", clear: "both" }}>
{dustbins.map(({ accepts, lastDroppedItem }, index) => (
<Dustbin
accept={accepts}
lastDroppedItem={lastDroppedItem}
onDrop={item => handleDrop(index, item)}
key={index}
/>
))}
</div>
<div style={{ overflow: "hidden", clear: "both" }}>
{boxes.map(({ name, type, id }, index) => (
<Box
key={id}
id={id}
name={name}
type={type}
isDropped={isDropped(name)}
/>
))}
</div>
</div>
);
};
export default Container;