fix: useDrag now properly updates isDragging for React cycle (#173)

This commit is contained in:
Cole Lawrence 2022-05-20 11:36:25 -04:00 committed by GitHub
parent bfc877ca8f
commit 9cf5c38aee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -5,6 +5,7 @@ import type {CapturedPointer} from '@theatre/studio/UIRoot/PointerCapturing'
import {usePointerCapturing} from '@theatre/studio/UIRoot/PointerCapturing' import {usePointerCapturing} from '@theatre/studio/UIRoot/PointerCapturing'
import noop from '@theatre/shared/utils/noop' import noop from '@theatre/shared/utils/noop'
import {isSafari} from './isSafari' import {isSafari} from './isSafari'
import useRefAndState from '@theatre/studio/utils/useRefAndState'
export enum MouseButton { export enum MouseButton {
Left = 0, Left = 0,
@ -172,8 +173,18 @@ export default function useDrag(
}>({onDrag: noop, onDragEnd: noop}) }>({onDrag: noop, onDragEnd: noop})
const capturedPointerRef = useRef<undefined | CapturedPointer>() const capturedPointerRef = useRef<undefined | CapturedPointer>()
// needed to have a state on the react lifecycle which can be updated
// via a ref (e.g. via the below layout effect).
const [isDraggingRef, isDragging] = useRefAndState(false)
useLayoutEffect(() => { useLayoutEffect(() => {
if (!target) return if (!target) return
const ensureIsDraggingUpToDateForReactLifecycle = () => {
const isDragging =
stateRef.current.domDragStarted && stateRef.current.detection.detected
if (isDraggingRef.current !== isDragging) {
isDraggingRef.current = isDragging
}
}
const dragHandler = (event: MouseEvent) => { const dragHandler = (event: MouseEvent) => {
if (!stateRef.current.domDragStarted) return if (!stateRef.current.domDragStarted) return
@ -199,6 +210,7 @@ export default function useDrag(
dragMovement: {x: 0, y: 0}, dragMovement: {x: 0, y: 0},
dragEventCount: 0, dragEventCount: 0,
} }
ensureIsDraggingUpToDateForReactLifecycle()
} }
} }
@ -234,6 +246,7 @@ export default function useDrag(
stateRef.current = {domDragStarted: false} stateRef.current = {domDragStarted: false}
if (opts.shouldPointerLock && !isSafari) document.exitPointerLock() if (opts.shouldPointerLock && !isSafari) document.exitPointerLock()
callbacksRef.current.onDragEnd(dragHappened) callbacksRef.current.onDragEnd(dragHappened)
ensureIsDraggingUpToDateForReactLifecycle()
} }
const addDragListeners = () => { const addDragListeners = () => {
@ -259,6 +272,7 @@ export default function useDrag(
detected: false, detected: false,
totalDistanceMoved: 0, totalDistanceMoved: 0,
} }
ensureIsDraggingUpToDateForReactLifecycle()
} }
} }
@ -299,6 +313,7 @@ export default function useDrag(
totalDistanceMoved: 0, totalDistanceMoved: 0,
}, },
} }
ensureIsDraggingUpToDateForReactLifecycle()
addDragListeners() addDragListeners()
} }
@ -319,12 +334,10 @@ export default function useDrag(
callbacksRef.current.onDragEnd?.(stateRef.current.detection.detected) callbacksRef.current.onDragEnd?.(stateRef.current.detection.detected)
} }
stateRef.current = {domDragStarted: false} stateRef.current = {domDragStarted: false}
ensureIsDraggingUpToDateForReactLifecycle()
} }
}, [target]) }, [target])
const isDragging =
stateRef.current.domDragStarted && stateRef.current.detection.detected
useCssCursorLock( useCssCursorLock(
isDragging && !!opts.lockCSSCursorTo, isDragging && !!opts.lockCSSCursorTo,
'dragging', 'dragging',