首页 > 解决方案 > 以正确的方式配置 react-dnd

问题描述

当前状态是使用fakeData对象数组。我的理解是,例如,当我移动时,Items状态之一应该根据我移动的位置进行更新,并且当状态更新时,组件App应该重新渲染。例如移动Items 2Folder 1和之间Item 1 and 4。但我不知道如何正确地做到这一点,而且我见过的大多数例子都是使用旧版本的 DnD。

最终目标是。

  1. 如何正确配置 DnD 以便我可以移动Items到其他文件夹?
  2. Folder组件可以通过拖动进行排序。
  3. (可选)添加动画,但我确信在 CSS 中我可以解决这个问题。

示例:https ://codesandbox.io/s/nifty-paper-3tz5o

代码:

const fakeData = [
  {
    folderName: "Folder 1",
    icon: "",
    children: [
      { name: "Item 1", icon: "Icon" },
      { name: "Item 4", icon: "Icon" }
    ]
  },
  {
    folderName: "Folder 2",
    icon: "",
    children: [{ name: "Item 2", icon: "Icon" }]
  },
  {
    folderName: "Folder 3",
    icon: "",
    children: [{ name: "Item 3", icon: "Icon" }]
  }
];

const DropFolder = ({ children, className, folderName }) => {
  const [, drop] = useDrop({
    accept: "Box",
    drop: () => ({ name: "Box" }),
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop()
    })
  });

  return (
    <div ref={drop} className={className}>
      <div className="folderName">{folderName}</div>
      <div className="container">{children}</div>
    </div>
  );
};

const MovableItem = ({ children, className, compName }) => {
  const [{ isDragging }, drag] = useDrag({
    type: "Box",
    item: { name: compName, type: "Box" },
    end: (item, monitor) => {
      console.log(item);
      const dropResult = monitor.getDropResult();
      console.log(dropResult);
    },
    collect: (monitor) => ({
      isDragging: monitor.isDragging()
    })
  });

  return (
    <div ref={drag} className={className} style={{ opacity: isDragging ? 0.7 : 1 }}>
      {children}
    </div>
  );
};

export default function App() {
  const [state, stateSet] = useState(fakeData);

  return (
    <div className="container">
      <DndProvider backend={HTML5Backend}>
        {state.map(({ folderName, children }, idx) => {
          return (
            <MovableItem key={idx} className="folder-container" compName={folderName}>
              <DropFolder className="column" folderName={folderName}>
                <>
                  {children.map(({ name }, idx) => {
                    return (
                      <MovableItem key={idx} className="movable-item" compName={name}>
                        {name}
                      </MovableItem>
                    );
                  })}
                </>
              </DropFolder>
            </MovableItem>
          );
        })}
      </DndProvider>
    </div>
  );
}

我知道还有其他库可以通过动画和更新的代码示例更好地处理这个问题,但我想弄清楚它是如何在 DnD 中完成的。根据我的理解,当我抓取一个项目时,我得到了正确的值,然后我需要获取项目被丢弃到的数据,一旦假设我有这两个日期(抓取的项目/目标),我就可以自己操纵状态.

标签: reactjsreact-dnd

解决方案


推荐阅读