在react-dnd中删除可拖动对象

时间:2020-05-19 03:16:02

标签: javascript reactjs react-dnd

我正在使用react-dnd。我想在使用可拖动对象后将其删除。我以react-dnd多类型示例为例,并在拖放时添加了删除。

当前行为: 1.拖动香蕉,右上方的垃圾箱将突出显示 2.将瓶子拖到左侧的任一垃圾桶中 3.再次拖动香蕉,现在突出显示了左侧的两个垃圾箱

预期的行为: 1.将瓶子拖到左侧的任一垃圾桶中 2.拖动香蕉,右上角应突出显示

这是怎么回事,我该如何解决?

https://codesandbox.io/s/pensive-wildflower-q2oxo?file=/src/Dustbin.jsx

1 个答案:

答案 0 :(得分:1)

您正在使用数组索引作为框的键并进行删除。处理项目删除操作时,请勿特别将索引用作键。而是,为Box保留唯一的ID。还要正确更新包装盒的状态。

Edit react dnd drag issue fix

代码段

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;