[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)
Grid:
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):
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>
}