React DND 嵌套拖动,drop 无法正常工作,ref.current 返回始终嵌套的元素

React DND nested drag,drop not working properly and ref.current returns always nested element

提问人:user0227 提问时间:11/28/2021 最后编辑:user0227 更新时间:11/29/2021 访问量:3703

问:

我正在使用 React-DnD 设置嵌套拖放。下图让您更好地了解我的方法。1

所有元素都是 Draggable 和 Droppable。示例 - 字段 1、2、组 1、字段 1、组 1 和子组 1 都可以拖放。

做过:

  1. 我可以对父项目字段 1、字段 2、组 1 进行排序 - 拖放,可排序

需要这方面的帮助:

  1. 需要对组内和组外的所有字段进行排序。
  2. 任何项目都可以分组和取消分组。

例:

场景 1:用户将字段 one 组 one 项目拖放到字段 2 下方。

场景 2:用户将拖动字段 2 项并将其拖放到组 1/子组 1 中。

每当我拖动使用以下行跟踪的项目时:将鼠标悬停在特定项目上时,ref.current 将给出特定项目。

import { useRef } from "react";
import { useDrag, useDrop } from "react-dnd";
import { ItemTypes } from "./ItemTypes";
const style = {
  border: "1px dashed gray",
  padding: "0.5rem 1rem",
  marginBottom: ".5rem",
  backgroundColor: "white",
  cursor: "move"
};
export const Card = ({ id, text, index, moveCard, children, type }) => {
  const ref = useRef(null);
  const [{ handlerId }, drop] = useDrop({
    accept: ItemTypes.CARD,
    collect(monitor) {
      return {
        handlerId: monitor.getHandlerId()
      };
    },
    hover(item, monitor) {
      if (!ref.current) {
        return;
      }
      const dragIndex = item.index;
      const hoverIndex = index;
      // Don't replace items with themselves
      if (dragIndex === hoverIndex) {
        return;
      }
      // Determine rectangle on screen
      const hoverBoundingRect = ref.current?.getBoundingClientRect();
      // Get vertical middle
      const hoverMiddleY =
        (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
      // Determine mouse position
      const clientOffset = monitor.getClientOffset();
      // Get pixels to the top
      const hoverClientY = clientOffset.y - hoverBoundingRect.top;
      // Only perform the move when the mouse has crossed half of the items height
      // When dragging downwards, only move when the cursor is below 50%
      // When dragging upwards, only move when the cursor is above 50%
      // Dragging downwards
      if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
        return;
      }
      // Dragging upwards
      if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
        return;
      }
      // Time to actually perform the action
      moveCard(dragIndex, hoverIndex);
      // Note: we're mutating the monitor item here!
      // Generally it's better to avoid mutations,
      // but it's good here for the sake of performance
      // to avoid expensive index searches.
      item.index = hoverIndex;
    }
  });
  const [{ isDragging }, drag] = useDrag({
    type: ItemTypes.CARD,
    item: () => {
      return { id, index };
    },
    collect: (monitor) => ({
      isDragging: monitor.isDragging()
    })
  });
  const opacity = isDragging ? 0 : 1;
  drag(drop(ref));
  return (
    <div
      className={type}
      ref={ref}
      style={{ ...style, opacity }}
      data-handler-id={handlerId}
    >
      <div style={{ paddingBottom: '15px' }}> 
        {text}
      </div>
      {children}
    </div>
  );
};

我尝试从组 1 拖动字段,但 ref.current 将组 1 显示为拖动项目。 下图说明了 ref.current 给出了第 1 组,但被拖动了字段、第 1 组、第 1 项 enter image description here

此处提供工作演示。任何这方面的帮助对我来说真的很有帮助。

注意:我一直在使用 React DnD 进行拖放,因此需要将其用于组项目和子组项目,无法切换到可能与现有 react dnd 冲突的其他库。

我可以在排序时使用 if (!monitor.isOver({ shallow: true })) return 来跟踪它; ref.current 在排序时给出正确的项目。沙盒已更新。问题是当我将一些新项目拖到已经删除的项目上时,当将鼠标悬停在组内的字段时,ref.current 会将组作为拖动项目。如何在将鼠标悬停在当前项目上时获取它?

JavaScript的 反应JS 拖放 嵌套列表 反应-DND

评论

0赞 pavi2410 3/4/2022
你找到任何解决方案了吗?

答: 暂无答案