Skip to content

Commit

Permalink
fix: always unsubscribe backend when connector reconnects (#1355)
Browse files Browse the repository at this point in the history
  • Loading branch information
upsuper authored and darthtrevino committed May 29, 2019
1 parent f59978e commit aeeb7c4
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 20 deletions.
36 changes: 22 additions & 14 deletions packages/react-dnd/src/SourceConnector.ts
Expand Up @@ -93,18 +93,22 @@ export default class SourceConnector implements Connector {
}

private reconnectDragSource() {
const dragSource = this.dragSource
if (!this.handlerId || !dragSource) {
return
}

// if nothing has changed then don't resubscribe
if (
const didChange =
this.didHandlerIdChange() ||
this.didConnectedDragSourceChange() ||
this.didDragSourceOptionsChange()
) {

if (didChange) {
this.disconnectDragSource()
}

const dragSource = this.dragSource
if (!this.handlerId || !dragSource) {
return
}

if (didChange) {
this.lastConnectedHandlerId = this.handlerId
this.lastConnectedDragSource = dragSource
this.lastConnectedDragSourceOptions = this.dragSourceOptions
Expand All @@ -117,18 +121,22 @@ export default class SourceConnector implements Connector {
}

private reconnectDragPreview() {
const dragPreview = this.dragPreview
if (!this.handlerId || !dragPreview) {
return
}

// if nothing has changed then don't resubscribe
if (
const didChange =
this.didHandlerIdChange() ||
this.didConnectedDragPreviewChange() ||
this.didDragPreviewOptionsChange()
) {

if (didChange) {
this.disconnectDragPreview()
}

const dragPreview = this.dragPreview
if (!this.handlerId || !dragPreview) {
return
}

if (didChange) {
this.lastConnectedHandlerId = this.handlerId
this.lastConnectedDragPreview = dragPreview
this.lastConnectedDragPreviewOptions = this.dragPreviewOptions
Expand Down
17 changes: 11 additions & 6 deletions packages/react-dnd/src/TargetConnector.ts
Expand Up @@ -38,17 +38,22 @@ export default class TargetConnector implements Connector {
}

public reconnect() {
const dropTarget = this.dropTarget
if (!this.handlerId || !dropTarget) {
return
}
// if nothing has changed then don't resubscribe
if (
const didChange =
this.didHandlerIdChange() ||
this.didDropTargetChange() ||
this.didOptionsChange()
) {

if (didChange) {
this.disconnectDropTarget()
}

const dropTarget = this.dropTarget
if (!this.handlerId || !dropTarget) {
return
}

if (didChange) {
this.lastConnectedHandlerId = this.handlerId
this.lastConnectedDropTarget = dropTarget
this.lastConnectedDropTargetOptions = this.dropTargetOptions
Expand Down
48 changes: 48 additions & 0 deletions packages/react-dnd/src/__tests__/SourceConnector.spec.tsx
@@ -0,0 +1,48 @@
import SourceConnector from '../SourceConnector'
import { Backend } from 'dnd-core'

describe('SourceConnector', () => {
let backend: jest.Mocked<Backend>
let connector: SourceConnector

beforeEach(() => {
backend = {
setup: jest.fn(),
teardown: jest.fn(),
connectDragSource: jest.fn(),
connectDragPreview: jest.fn(),
connectDropTarget: jest.fn(),
}
connector = new SourceConnector(backend)
})

it('unsubscribes drag source when clearing handler id', () => {
const unsubscribeDragSource = jest.fn()
backend.connectDragSource.mockReturnValueOnce(unsubscribeDragSource)

connector.receiveHandlerId('test')
connector.hooks.dragSource()({})
expect(backend.connectDragSource).toHaveBeenCalled()
expect(unsubscribeDragSource).not.toHaveBeenCalled()
backend.connectDragSource.mockClear()

connector.receiveHandlerId(null)
expect(backend.connectDragSource).not.toHaveBeenCalled()
expect(unsubscribeDragSource).toHaveBeenCalled()
})

it('unsubscribes drag preview when clearing handler id', () => {
const unsubscribeDragPreview = jest.fn()
backend.connectDragPreview.mockReturnValueOnce(unsubscribeDragPreview)

connector.receiveHandlerId('test')
connector.hooks.dragPreview()({})
expect(backend.connectDragPreview).toHaveBeenCalled()
expect(unsubscribeDragPreview).not.toHaveBeenCalled()
backend.connectDragPreview.mockClear()

connector.receiveHandlerId(null)
expect(backend.connectDragPreview).not.toHaveBeenCalled()
expect(unsubscribeDragPreview).toHaveBeenCalled()
})
})
26 changes: 26 additions & 0 deletions packages/react-dnd/src/__tests__/TargetConnector.spec.tsx
@@ -0,0 +1,26 @@
import TargetConnector from '../TargetConnector'

describe('TargetConnector', () => {
it('unsubscribes drop target when clearing handler id', () => {
const backend = {
setup: jest.fn(),
teardown: jest.fn(),
connectDragSource: jest.fn(),
connectDragPreview: jest.fn(),
connectDropTarget: jest.fn(),
}
const connector = new TargetConnector(backend)
const unsubscribeDropTarget = jest.fn()
backend.connectDropTarget.mockReturnValueOnce(unsubscribeDropTarget)

connector.receiveHandlerId('test')
connector.hooks.dropTarget()({})
expect(backend.connectDropTarget).toHaveBeenCalled()
expect(unsubscribeDropTarget).not.toHaveBeenCalled()
backend.connectDropTarget.mockClear()

connector.receiveHandlerId(null)
expect(backend.connectDropTarget).not.toHaveBeenCalled()
expect(unsubscribeDropTarget).toHaveBeenCalled()
})
})

0 comments on commit aeeb7c4

Please sign in to comment.