I ran into an interesting bug today while I was writing some tests for a hover
handler. The relevant code is here.
During a drag operation, for any drop target that the drag operation goes through, for the first frame of that hover incident, isOver
will incorrectly return false
in the hover
handler. This is because that handler is called before the drop target is registered as being hovered over in the monitor's store.
I have a hover
handler that looks like this:
hover(props, monitor, _component) {
if (!monitor.isOver({ shallow: true })) {
return undefined;
}
do_the_thing();
}
In normal use this probably doesn't matter, as you'd be hovering for more than one frame. In tests, however, it's easy to trigger. With the following test code, the do_the_thing()
part never happens.
backend.simulateBeginDrag([ dragSources.get(0).getHandlerId() ]);
backend.simulateHover([ dropTargets.get(1).getHandlerId() ], { clientOffset: { x: 50, y: 35 } });
backend.simulateDrop();
backend.simulateEndDrag();
What I've done for now to work around this is call simulateHover
twice. What this does is triggers two calls to hover
- one where the drop target is not yet registered, and one where it is.
backend.simulateBeginDrag([ dragSources.get(0).getHandlerId() ]);
backend.simulateHover([ dropTargets.get(1).getHandlerId() ]);
backend.simulateHover([ dropTargets.get(1).getHandlerId() ], { clientOffset: { x: 50, y: 35 } });
backend.simulateDrop();
backend.simulateEndDrag();
What a fun bug!