React-dnd: 当 DOM 中的元素在拖动事件中出现/消失时,HTML5Backend 停止拖动:CHROME

创建于 2020-04-01  ·  3评论  ·  资料来源: react-dnd/react-dnd

描述错误
html5backend 存在严重问题。 我们需要生成一些间隙来引导用户将拖动的元素放在哪里,我们希望这些间隙仅在元素拖动时可见。
在 Firefox 中完美运行,但在 chrome 中,卡片在开始拖动事件后立即启动停止拖动事件。

再生产
https://codesandbox.io/s/react-dnd-sortable-holes-bq2oe
每张卡片都是可拖动的,当用户开始拖动时会出现橙色间隙。
image

image

在 Firefox 中就像一个魅力,但在 chrome 中,停止事件是在开始事件之后立即启动的。

正如您在控制台中看到的:
image

  • 操作系统:[例如 iOS]
  • 浏览器:Chrome 版本 80.0.3987.162 中的错误,在 Firefox 74.0(64 位)中完美运行

任何帮助将不胜感激,我们真的需要这个功能。

最有用的评论

我们的团队已经改进了状态解决方法,为拖放提供程序创建了一个自定义挂钩,无论如何,你们中的任何人都面临这个问题,这里是一个解决错误的解决方案。

https://codesandbox.io/s/react-dnd-sortable-gaps-custom-9tl13

主要部分包括定义一个 Context 和一个 Provider 来存储拖动状态。

const DndContext = React.createContext([{}, () => {}]);

const DndCustomProvider = props => {
  const [state, setState] = useState({ dragging: false });

  return (
    <DndProvider backend={props.backend}>
      <DndContext.Provider value={[state, setState]}>
        {props.children}
      </DndContext.Provider>
    </DndProvider>
  );
};

其次,在拖动开始函数中使用 setTimeout 可以避免结束调度。

  const [context, setContext] = useContext(DndContext);

  const [collected, dragRef] = useDrag({
    ...,
    begin: monitor => {
      setTimeout(() => {
        setContext(() => ({ dragging: true }));
      }, 0);

      if (begin) {
        begin(monitor);
      }
    },
    end: (item, monitor) => {
      setContext(() => ({ dragging: false }));

      if (end) {
        end(item, monitor);
      }
    },
    ...
  });

  return [
    {
      ...collected,
      isDragging: context.dragging
    },
    dragRef
  ];

最后,isDragging 收集的值被上下文值覆盖。

所有3条评论

我找到了一个解决方法,阅读了很多,对于这个问题,设置一个超时和一个我通过组件传递的状态变量,我不太喜欢它,因为在这些简单的情况下它很容易做到,但在复杂的情况下情况下我应该使用上下文或类似的东西来使一切正常。
https://codesandbox.io/s/react-dnd-sortable-holes-vxeus

我希望您能指导我通过更好的解决方案,我想使用库中的 isDragging 而不是这种解决方法。

我们的团队已经改进了状态解决方法,为拖放提供程序创建了一个自定义挂钩,无论如何,你们中的任何人都面临这个问题,这里是一个解决错误的解决方案。

https://codesandbox.io/s/react-dnd-sortable-gaps-custom-9tl13

主要部分包括定义一个 Context 和一个 Provider 来存储拖动状态。

const DndContext = React.createContext([{}, () => {}]);

const DndCustomProvider = props => {
  const [state, setState] = useState({ dragging: false });

  return (
    <DndProvider backend={props.backend}>
      <DndContext.Provider value={[state, setState]}>
        {props.children}
      </DndContext.Provider>
    </DndProvider>
  );
};

其次,在拖动开始函数中使用 setTimeout 可以避免结束调度。

  const [context, setContext] = useContext(DndContext);

  const [collected, dragRef] = useDrag({
    ...,
    begin: monitor => {
      setTimeout(() => {
        setContext(() => ({ dragging: true }));
      }, 0);

      if (begin) {
        begin(monitor);
      }
    },
    end: (item, monitor) => {
      setContext(() => ({ dragging: false }));

      if (end) {
        end(item, monitor);
      }
    },
    ...
  });

  return [
    {
      ...collected,
      isDragging: context.dragging
    },
    dragRef
  ];

最后,isDragging 收集的值被上下文值覆盖。

有没有人对此问题有不涉及这种解决方法的补丁的解决方案或想法?

此页面是否有帮助?
0 / 5 - 0 等级