删除react-dnd中的可拖动对象
Delete draggable object in react-dnd
我正在使用 react-dnd。我想在使用后删除一个可拖动对象。我采用了 react-dnd 多类型示例并添加了一个删除删除。
当前行为:
1. 拖动 Banana,右上角垃圾箱高亮显示
2. 将 Bottle 拖入左侧任一垃圾箱
3.再次拖动Banana,此时左边两个垃圾桶高亮显示
预期行为:
1. 将 Bottle 拖入左侧任一垃圾箱
2.拖动Banana,右上角要高亮
这是怎么回事,我该如何解决?
https://codesandbox.io/s/pensive-wildflower-q2oxo?file=/src/Dustbin.jsx
您正在使用数组索引作为框的键并进行删除。在处理项目删除操作时,不要专门使用索引作为键。相反,为 Boxes 维护一个唯一的 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;
我正在使用 react-dnd。我想在使用后删除一个可拖动对象。我采用了 react-dnd 多类型示例并添加了一个删除删除。
当前行为: 1. 拖动 Banana,右上角垃圾箱高亮显示 2. 将 Bottle 拖入左侧任一垃圾箱 3.再次拖动Banana,此时左边两个垃圾桶高亮显示
预期行为: 1. 将 Bottle 拖入左侧任一垃圾箱 2.拖动Banana,右上角要高亮
这是怎么回事,我该如何解决?
https://codesandbox.io/s/pensive-wildflower-q2oxo?file=/src/Dustbin.jsx
您正在使用数组索引作为框的键并进行删除。在处理项目删除操作时,不要专门使用索引作为键。相反,为 Boxes 维护一个唯一的 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;