react-dnd / react-dnd

Drag and Drop for React

Home Page:http://react-dnd.github.io/react-dnd

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Question] Working with DnD and PrimeReact's DataTable

GuiRodriguero opened this issue · comments

So I'm currently working on a new React page that uses PrimeReact's DataTable and React DnD.
On this page, the user will be able to drag a specific table cell, to a grid
Cell: (the other cells of this table are irrelevant)
image
Grid:
image

I managed to implement the drag and drop correctly (nice documentation btw :))

Main.tsx:

const [list, setList] = useState<...>(...)

myDropMethod = () => {...}

return (
        <>
            <Table list={list} />
            <Grid />
        </>
    )

Table.tsx:

    const myNumberBody = (rowData) => {
        return <MyNumber number={rowData.myNumber} />
    }
    return (
        <DataTable value={[...list]}>
            <Column field="..." header="..." body={myNumberBody} />
        </DataTable>
    )

MyNumber.tsx (drag) :

export const MyNumber = ({myNumber}) {
    const [, drag] = useDrag(() => ({
        type: 'MyNumber',
        item: { myNumber: myNumber },
    }))

    return <div ref={drag}>{myNumber}</div>
}

Grid.tsx (drop) :

const [myNumber, setMyNumber] = useState<...>(...)

    const [{ isOver }, drop] = useDrop({
        accept: 'MyNumber',
        drop: () => myDropMethod(),
        collect: (monitor) => ({
            isOver: !!monitor.isOver(),
        }),
    })

    return (
        <div ref={drop}>
            <MyNumber myNumber={myNumber!} />
        </div>
    )

To improve my page's UX, I decide to remove the rows that were dropped on my grid. To do that, i changed the myDropMethod on my Main.tsx:

myDropMethod = (myNumber) => {
    setList((oldList) => oldList.filter(number) => number !== myNumber)
}

So, theoretically, if my list is: [1, 2, 3] and I drag and drop the number 1, "myNumber" will be 1 and my list will turn into [2, 3]
(And that's what it happens):
image
image

The problem is that, when I try to move the number 2 (whose index is now 0), "myNumber" will still be number 1 and it won't drag to my Grid... If I try to move the number 3 (whose index is now 1), "myNumber" will be number 2 (not 3).

So it seems like DnD is using the original list instead of the one that was filtered on myDropMethod()
Is this supossed to happen? Am I doing something wrong?

It turns out that that I was missing 'deps' on my useDrag:

export const MyNumber = ({myNumber}) {
    const [, drag] = useDrag(() => ({
        type: 'MyNumber',
        item: { myNumber },
    }), [myNumber])

    return <div ref={drag}>{myNumber}</div>
}