Skip to content

Commit 365cbc3

Browse files
committed
refactor(Interactive): optimize event handling and improve performance.
1 parent 73a420f commit 365cbc3

File tree

1 file changed

+24
-17
lines changed

1 file changed

+24
-17
lines changed

packages/drag-event-interactive/src/index.tsx

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,44 +24,51 @@ const Interactive = React.forwardRef<HTMLDivElement, InteractiveProps>((props, r
2424
hasTouched.current = isTouch(event);
2525
return true;
2626
};
27-
2827
const handleMove = useCallback(
2928
(event: MouseEvent | TouchEvent) => {
3029
preventDefaultMove(event);
31-
// If user moves the pointer outside of the window or iframe bounds and release it there,
32-
// `mouseup`/`touchend` won't be fired. In order to stop the picker from following the cursor
33-
// after the user has moved the mouse/finger back to the document, we check `event.buttons`
34-
// and `event.touches`. It allows us to detect that the user is just moving his pointer
35-
// without pressing it down
30+
if (!container.current) return;
31+
3632
const isDown = isTouch(event) ? event.touches.length > 0 : event.buttons > 0;
37-
if (isDown && container.current) {
38-
onMoveCallback && onMoveCallback(getRelativePosition(container.current!, event), event);
39-
} else {
33+
if (!isDown) {
4034
setDragging(false);
35+
return;
4136
}
37+
38+
onMoveCallback?.(getRelativePosition(container.current, event), event);
4239
},
4340
[onMoveCallback],
4441
);
4542

4643
const handleMoveEnd = useCallback(() => setDragging(false), []);
47-
const toggleDocumentEvents = useCallback((state: boolean) => {
48-
const toggleEvent = state ? window.addEventListener : window.removeEventListener;
49-
toggleEvent(hasTouched.current ? 'touchmove' : 'mousemove', handleMove);
50-
toggleEvent(hasTouched.current ? 'touchend' : 'mouseup', handleMoveEnd);
51-
}, []);
44+
const toggleDocumentEvents = useCallback(
45+
(state: boolean) => {
46+
if (state) {
47+
window.addEventListener(hasTouched.current ? 'touchmove' : 'mousemove', handleMove);
48+
window.addEventListener(hasTouched.current ? 'touchend' : 'mouseup', handleMoveEnd);
49+
} else {
50+
window.removeEventListener('mousemove', handleMove);
51+
window.removeEventListener('mouseup', handleMoveEnd);
52+
window.removeEventListener('touchmove', handleMove);
53+
window.removeEventListener('touchend', handleMoveEnd);
54+
}
55+
},
56+
[handleMove, handleMoveEnd],
57+
);
5258

5359
useEffect(() => {
5460
toggleDocumentEvents(isDragging);
5561
return () => {
56-
isDragging && toggleDocumentEvents(false);
62+
toggleDocumentEvents(false);
5763
};
58-
}, [isDragging, toggleDocumentEvents]);
64+
}, [isDragging, handleMove, handleMoveEnd, toggleDocumentEvents]);
5965

6066
const handleMoveStart = useCallback(
6167
(event: React.MouseEvent | React.TouchEvent) => {
6268
preventDefaultMove(event.nativeEvent);
6369
if (!isValid(event.nativeEvent)) return;
64-
onKeyCallback && onKeyCallback(getRelativePosition(container.current!, event.nativeEvent), event.nativeEvent);
70+
if (!container.current) return;
71+
onKeyCallback?.(getRelativePosition(container.current, event.nativeEvent), event.nativeEvent);
6572
setDragging(true);
6673
},
6774
[onKeyCallback],

0 commit comments

Comments
 (0)