React DnD иногда перетаскивание не удается

Я использую React DnD. В первый раз все работает. Но во второй раз это произошло. Компонент не двигается. Вот мои codeы.

App.tsx

GroupDnDTable.tsx

GroupDnDRow.tsx

Я пытался решить это, но не смог найти проблему. Я думаю, что я неправильно его использую, но не знаю, в чем проблема.

Я пробовал со своими codeами. Хочу решить свои проблемы.

import { useState } from 'react'
import './App.css'
import GroupDnDTable from './components/GroupDnDTable';

function App() {
  const [orderedGroup, setOrderedGroup] = useState([
    {
      "largeGrpNo": 1,
      "largeGrpNm": "test1",
      "smallGrp": [
        {
          "smallGrpNo": 4,
          "smallGrpNm": "test2",
          "facility": [
            {
              "facilityNo": 9285,
              "facilityNm": "1"
            },
            {
              "facilityNo": 36005,
              "facilityNm": "2"
            },
            {
              "facilityNo": 40001,
              "facilityNm": "test"
            },
            {
              "facilityNo": 41005,
              "facilityNm": "3"
            }
          ]
        },
        {
          "smallGrpNo": 5,
          "smallGrpNm": "test2",
          "facility": [
            {
              "facilityNo": 9286,
              "facilityNm": " test2 "
            },
            {
              "facilityNo": 36005,
              "facilityNm": "test2"
            }
          ]
        }
      ]
    },
    {
      "largeGrpNo": 3,
      "largeGrpNm": "test3",
      "smallGrp": [
        {
          "smallGrpNo": 1004,
          "smallGrpNm": "test1111",
          "facility": [
            {
              "facilityNo": 40001,
              "facilityNm": "test222"
            },
            {
              "facilityNo": 41005,
              "facilityNm": "test3333"
            }
          ]
        }
      ]
    },
    {
      "largeGrpNo": 2001,
      "largeGrpNm": "test444",
      "smallGrp": [
        {
          "smallGrpNo": 2004,
          "smallGrpNm": "test2",
          "facility": [
            {
              "facilityNo": 40001,
              "facilityNm": "test"
            },
            {
              "facilityNo": 41005,
              "facilityNm": "test"
            }
          ]
        },
        {
          "smallGrpNo": 2003,
          "smallGrpNm": "test222",
          "facility": [
            {
              "facilityNo": null,
              "facilityNm": null
            }
          ]
        },
        {
          "smallGrpNo": 2005,
          "smallGrpNm": "test",
          "facility": [
            {
              "facilityNo": null,
              "facilityNm": null
            }
          ]
        }
      ]
    },
    {
      "largeGrpNo": 1001,
      "largeGrpNm": "test",
      "smallGrp": []
    },
    {
      "largeGrpNo": 2002,
      "largeGrpNm": "test12344",
      "smallGrp": []
    },
    {
      "largeGrpNo": 3001,
      "largeGrpNm": "test",
      "smallGrp": [
        {
          "smallGrpNo": 3002,
          "smallGrpNm": "hello",
          "facility": [
            {
              "facilityNo": null,
              "facilityNm": null
            }
          ]
        }
      ]
    }]);
  return (
    <div>
      <GroupDnDTable
        orderedGroup={orderedGroup}
        setOrderedGroup={setOrderedGroup}
      ></GroupDnDTable>
    </div>
  )
}

export default App
import update from 'immutability-helper'

import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import GroupDnDRow from "./GroupDnDRow";

const GroupDnDTable = ({ orderedGroup, setOrderedGroup, }: any) => {
  const moveCard = (dragIndex: number, hoverIndex: number) => {
    setOrderedGroup((prevCards: any) =>
      update(prevCards, {
        $splice: [
          [dragIndex, 1],
          [hoverIndex, 0, prevCards[dragIndex]],
        ],
      }));
  };
  const renderCard = (group: any, index: number) => {
    return (
      <GroupDnDRow
        key={group.largeGrpNo}
        index={index}
        id={group.largeGrpNo}
        group={group}
        moveCard={moveCard}
      />
    );
  };
  const groupList = orderedGroup ? orderedGroup.map((group: any, i: number) => renderCard(group, i)) : [];
  return <DndProvider backend={HTML5Backend}>
    {
      groupList
    }
  </DndProvider>;
};

export default GroupDnDTable;
import { useEffect, useRef } from "react";
import { useDrag, useDrop } from "react-dnd";

const ItemTypes = {
    FAC_GRP: 'fac_grp',
};
const GroupDnDRow = ({
    moveCard, index, group, id,
}: any) => {

    const ref = useRef(null);
    const [{ handlerId }, drop] = useDrop({
        accept: ItemTypes.FAC_GRP,
        collect(monitor) {
            return {
                handlerId: monitor.getHandlerId(),
            }
        },
        hover(item: any, monitor) {
            if (!ref.current) {
                return;
            }
            const dragIndex = item.index;
            const hoverIndex = index;
            if (dragIndex === hoverIndex) {
                return;
            }
            const current = ref.current as any;
            const hoverBoundingRect = current.getBoundingClientRect();
            const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
            const clientOffset = monitor.getClientOffset();
            const hoverClientY = clientOffset ? clientOffset.y - hoverBoundingRect.top : 0;
            // Dragging downwards
            if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
                return;
            }
            // Dragging upwards
            if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
                return;
            }
            moveCard(dragIndex, hoverIndex);
            item.index = hoverIndex;
        }
    });

    const [_v, drag] = useDrag(() => ({
        type: ItemTypes.FAC_GRP,
        item: () => {
            console.log(id, index);
            return { id, index }
        },
        collect: (monitor) => ({
            isDragging: monitor.isDragging(),
        }),
    }));
    drag(drop(ref));

    let smallRows = group.smallGrp.map((smallGrp:any, idx:number) => {
        const f = smallGrp.facility.map(({ facilityNm }: {facilityNm: string}) => facilityNm);
        const facilities = f.join(', ');
        return (
            <div  key={`smallgrp_${idx}`}>
                <div >
                    <div >
                        {smallGrp.smallGrpNm}
                    </div>
                    <div ></div>
                    <div >
                        {facilities}
                    </div>
                    <div >{idx + 1}</div>
                </div>
            </div>
        );
    });


    return (
        <div style={{ border: '1px solid', borderRadius: '5px'}} ref={ref} data-handler-id={handlerId} key={`dnd_${index}`}>
            <div>
                <div>
                    <em></em>
                    <strong contentEditable="false" suppressContentEditableWarning>{group.largeGrpNm}</strong>
                </div>
            </div>

            <div>
                <div>
                    <div>list</div>
                    <div></div>
                    <div>somthing</div>
                    <div>order</div>
                </div>
                <div>
                    {smallRows}
                </div>
            </div>
        </div>
    );
};

export default GroupDnDRow;
Максим
Вопрос задан5 июня 2024 г.

1 Ответ

2
Орест
Ответ получен18 сентября 2024 г.

Ваш ответ

Загрузить файл.