Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: don't lose drag source/preview if disconnected and immediately reconnected #3565

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jtbandes
Copy link

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" } }) and useEffect(() => setValue(1)):

  • The setValue call triggers the component to render again.
  • A new options object { dropEffect: "copy" } is allocated and passed into useDrag.
  • Since dragSourceOptions is a dependency for this useLayoutEffect, connector.disconnectDragSource() and connector.reconnect() are called:
    useIsomorphicLayoutEffect(() => {
    connector.dragSourceOptions = dragSourceOptions || null
    connector.reconnect()
    return () => connector.disconnectDragSource()
    }, [connector, dragSourceOptions])
  • Inside reconnectDragSource(), didChange is set to false because didDragSourceOptionsChange returns false. It returns false because the new dragSourceOptions are shallowEqual to the previous options.
    private reconnectDragSource(): boolean {
    const dragSource = this.dragSource
    // if nothing has changed then don't resubscribe
    const didChange =
    this.didHandlerIdChange() ||
    this.didConnectedDragSourceChange() ||
    this.didDragSourceOptionsChange()
    private didDragSourceOptionsChange(): boolean {
    return !shallowEqual(
    this.lastConnectedDragSourceOptions,
    this.dragSourceOptions,
    )
    }

This patch fixes the bug by adding extra state variables, isDragSourceConnected & isDragPreviewConnected. When these are false, backend.connectDragSource & backend.connectDragPreview will be called.

@jtbandes
Copy link
Author

Hi @darthtrevino – do you think there's a chance you'd have time to look at this in the near future, or do you know when you might get a chance? Thanks for your work on this library 🙌

jtbandes added a commit to foxglove/studio that referenced this pull request May 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant