Reputation: 1857
I am learning react hooks and learn best by doing.
I thought id do something fun and found an online tutorial on how to implement drag and drop using react. This was done with class components so I challanged myself by changing it up and doing it with hooks.
What I am after:
left side is like a table with chairs. Each green area is a chair we can drop an item to.
Right side: Is like a bag of items that are there to be placed in their own "chair". Like a temporary place before a user places it on a chair
Problem:
I can drag an item from left to right side with no problems BUT when draging from right side to left the item gets dropped on the left side but is also kept on the right side.
I figured I have to be using the same set of data everywhere so all child components inherit data from the parent and when the data is updated in one component via setDragables
I figured everything would update but it is not the case...
Its alot of code so I created this sandbox.
Thankful for any ideas!
Upvotes: 2
Views: 1125
Reputation: 208
I struggled to navigate your code as there was a lot there.
It seems that the main issue is that it is not re-rendering when you go from left to right, but is correctly re-rendering when going right to left. When you make multiple drag drop action the right list is updated to have the correct values that it should have had for the previous drag drop. So looking further into why its not re-rendering would be beneficial.
I did come up with a solution to fix your code sandbox code, although this is definitely not the most elegant way and there are many other ways to solve this issue. The way I decided to fix this issue is to have state that gets updated when the Dragables is updated using the useEffect hook. I then created state for the unassigned.
The code sandbox link is here https://codesandbox.io/s/react-hooks-usestate-35chk?fontsize=14&hidenavigation=1&theme=dark
The only changes I made was to the MyFuncApp function, and I think I changed the DropslotNumber of the 'Go To Gym' item to be 0 instead of it being pushed into the unassigned array like you originally had it.
const initial = Dragables.filter(i => {
return i.DropSlotId === 0;
});
const [unassigned, setUnassigned] = useState(initial);
const onDragEnd = (event, newPos, data) => {
setUnassigned(curr => curr.filter(item => item.CId !== data));
//post
};
useEffect(() => {
setUnassigned(
Dragables.filter(i => {
return i.DropSlotId === 0;
})
);
}, [Dragables]);
This code snippet above is the main change made. Creating the initial state by filtering all items that are in drop slot 0. Being the right side. The useEffect is used for updating the unassigned list by viewing when the Dragables data is changed and then updating the list correctly. The other part is the onDragDrop that is making sure the id is removed from the unassigned list. It is currently using the CId that you have on the items, although you might want to change that.
To use the CId I modified your function call for the onDragEnd for the unassigned items to be as follows
onDragEnd={event => {
onDragEnd(event, p.refArea, p.CId);
}}
Hopefully my code is a little bit helpful
Good luck!
Upvotes: 2