3

Looks like React DnD expects draggable/droppable items to be siblings in order to work properly. If one of the items belongs to another parent I get "Expected to find a valid target." as soon as the drag over event fires (when the swap should trigger).

I tweaked an example from their docs in case anyone would like to try it out: broken example: https://codesandbox.io/s/broken-feather-qf0f2?file=/src/Container.jsx

Tweaks are at the bottom. Note that the first card item is rendered separately from the remaining ones, in another div.

In order to trigger the error just drag & drop the first item into another one. Notice that if you drag & drop any other items they will work.

original example: https://codesandbox.io/s/github/react-dnd/react-dnd/tree/gh-pages/examples_hooks_js/04-sortable/simple?from-embed=&file=/src/Container.jsx

Thank you!

4 Answers 4

1

Could be an issue with react-dnd.

Check out this issue https://github.com/react-dnd/react-dnd/issues/361

1

From the issue that I had, the hover handler was updating the table/grid too fast. It was setting the state of the items and I guess DnD applies a new target id, hence the error.

Try adding a debounce on the hover handler with trailing option set to true. The problem is that the component is updating too quickly and the target id that DnD is expecting, has already changed due to the state change. It may help to add some checks in there to make sure that the item is droppable as well.

1

Due to @DDT's answer, I managed to solve the problem I was experiencing.

In the useDrop function I was updating the table/grid too fast after the update function from immutability-helper.

So I added a state variable e.g. wasDragDropped with an useEffect hook on it. I change the wasDragDropped variable when useDrag is finished, and then update the table/grid via functionality in the useEffect hook.

(using react-dnd 14.0.4 and react-dnd-html5-backend 14.0.2)

1

I also run in that issue, and as it is in aswers above, my problem was that component is updating too fast. I just add setTimout before updating state - and it's work (without useEffect and debounce).

function moveItems(dragged: string, hovered: string) {
const newWidgets = move(dragged, hovered, widgets); // calculation of positions etc
setTimeout(() => setWidgets(newWidgets), 0);

}

1

Not the answer you're looking for? Browse other questions tagged or ask your own question.