fix: don't lose drag source/preview if disconnected and immediately reconnected #3565
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This fixes a bug demonstrated in the following codesandbox. One drag source works, and the other does not.
https://codesandbox.io/s/xenodochial-christian-nu3rlw?file=/src/App.tsx
Screen.Recording.2023-04-27.at.9.51.40.AM.mov
I first encountered this bug in 14.0.3, so I think it was introduced in #3290. At the time I skipped upgrading this package because I couldn't resolve it. Here we are 1.5 years later and it seems like the bug is still present 😅
The bug is triggered by the combination of
useDrag({ ... options: { dropEffect: "copy" } })
anduseEffect(() => setValue(1))
:setValue
call triggers the component to render again.{ dropEffect: "copy" }
is allocated and passed into useDrag.dragSourceOptions
is a dependency for thisuseLayoutEffect
,connector.disconnectDragSource()
andconnector.reconnect()
are called:react-dnd/packages/react-dnd/src/hooks/useDrag/useDragSourceConnector.ts
Lines 20 to 24 in 7c88c37
reconnectDragSource()
, didChange is set to false because didDragSourceOptionsChange returns false. It returns false because the newdragSourceOptions
areshallowEqual
to the previous options.react-dnd/packages/react-dnd/src/internals/SourceConnector.ts
Lines 101 to 107 in 7c88c37
react-dnd/packages/react-dnd/src/internals/SourceConnector.ts
Lines 179 to 184 in 7c88c37
This patch fixes the bug by adding extra state variables,
isDragSourceConnected
&isDragPreviewConnected
. When these are false,backend.connectDragSource
&backend.connectDragPreview
will be called.