From 86423e118bb9d32d48028e350d473019678c2389 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Wed, 12 Nov 2025 13:52:06 +0100 Subject: [PATCH] Memoze event handlers --- .../js/useGestureStateChangeEvent.ts | 8 +-- .../callbacks/js/useGestureTouchEvent.ts | 8 +-- .../callbacks/js/useGestureUpdateEvent.ts | 22 ++++++--- .../src/v3/hooks/useGesture.ts | 49 ++++++++++++++----- 4 files changed, 61 insertions(+), 26 deletions(-) diff --git a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/js/useGestureStateChangeEvent.ts b/packages/react-native-gesture-handler/src/v3/hooks/callbacks/js/useGestureStateChangeEvent.ts index d0832597f1..16a8ba4b4b 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/js/useGestureStateChangeEvent.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/callbacks/js/useGestureStateChangeEvent.ts @@ -1,3 +1,4 @@ +import { useMemo } from 'react'; import { BaseGestureConfig } from '../../../types'; import { extractStateChangeHandlers } from '../../utils'; import { getStateChangeHandler } from '../stateChangeHandler'; @@ -6,7 +7,8 @@ export function useGestureStateChangeEvent( handlerTag: number, config: BaseGestureConfig ) { - const handlers = extractStateChangeHandlers(config); - - return getStateChangeHandler(handlerTag, handlers); + return useMemo(() => { + const handlers = extractStateChangeHandlers(config); + return getStateChangeHandler(handlerTag, handlers); + }, [handlerTag, config]); } diff --git a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/js/useGestureTouchEvent.ts b/packages/react-native-gesture-handler/src/v3/hooks/callbacks/js/useGestureTouchEvent.ts index f7eea78714..92ef9b06f6 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/js/useGestureTouchEvent.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/callbacks/js/useGestureTouchEvent.ts @@ -1,3 +1,4 @@ +import { useMemo } from 'react'; import { BaseGestureConfig } from '../../../types'; import { extractTouchHandlers } from '../../utils'; import { getTouchEventHandler } from '../touchEventHandler'; @@ -6,7 +7,8 @@ export function useGestureTouchEvent( handlerTag: number, config: BaseGestureConfig ) { - const handlers = extractTouchHandlers(config); - - return getTouchEventHandler(handlerTag, handlers); + return useMemo(() => { + const handlers = extractTouchHandlers(config); + return getTouchEventHandler(handlerTag, handlers); + }, [handlerTag, config]); } diff --git a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/js/useGestureUpdateEvent.ts b/packages/react-native-gesture-handler/src/v3/hooks/callbacks/js/useGestureUpdateEvent.ts index 6179273192..5219c1cc3f 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/js/useGestureUpdateEvent.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/callbacks/js/useGestureUpdateEvent.ts @@ -2,18 +2,26 @@ import { extractUpdateHandlers, isAnimatedEvent } from '../../utils'; import { ReanimatedContext } from '../../../../handlers/gestures/reanimatedWrapper'; import { getUpdateHandler } from '../updateHandler'; import { BaseGestureConfig } from '../../../types'; +import { useMemo } from 'react'; export function useGestureUpdateEvent( handlerTag: number, config: BaseGestureConfig ) { - const { handlers, changeEventCalculator } = extractUpdateHandlers(config); + return useMemo(() => { + const { handlers, changeEventCalculator } = extractUpdateHandlers(config); - const jsContext: ReanimatedContext = { - lastUpdateEvent: undefined, - }; + const jsContext: ReanimatedContext = { + lastUpdateEvent: undefined, + }; - return isAnimatedEvent(config.onUpdate) - ? undefined - : getUpdateHandler(handlerTag, handlers, jsContext, changeEventCalculator); + return isAnimatedEvent(config.onUpdate) + ? undefined + : getUpdateHandler( + handlerTag, + handlers, + jsContext, + changeEventCalculator + ); + }, [handlerTag, config]); } diff --git a/packages/react-native-gesture-handler/src/v3/hooks/useGesture.ts b/packages/react-native-gesture-handler/src/v3/hooks/useGesture.ts index 6a641d2b05..50ae603d3a 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/useGesture.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/useGesture.ts @@ -1,4 +1,4 @@ -import { useEffect, useMemo } from 'react'; +import { useEffect, useMemo, useRef } from 'react'; import { getNextHandlerTag } from '../../handlers/getNextHandlerTag'; import RNGestureHandlerModule from '../../RNGestureHandlerModule'; import { useGestureCallbacks } from './useGestureCallbacks'; @@ -69,12 +69,20 @@ export function useGesture( throw new Error(tagMessage('Failed to create reanimated event handlers.')); } - const gestureRelations = prepareRelations(config, tag); + const gestureRelations = useMemo( + () => prepareRelations(config, tag), + [config, tag] + ); - useMemo(() => { + const currentGestureRef = useRef({ type: '', tag: -1 }); + if ( + currentGestureRef.current.tag !== tag || + currentGestureRef.current.type !== (type as string) + ) { + currentGestureRef.current = { type, tag }; RNGestureHandlerModule.createGestureHandler(type, tag, {}); RNGestureHandlerModule.flushOperations(); - }, [type, tag]); + } useEffect(() => { return () => { @@ -93,13 +101,28 @@ export function useGesture( return () => { unbindSharedValues(config, tag); }; - }, [tag, config]); + }, [tag, config, type]); - return { - tag, - type, - config, - detectorCallbacks: { + return useMemo( + () => ({ + tag, + type, + config, + detectorCallbacks: { + onGestureHandlerStateChange, + onGestureHandlerEvent, + onGestureHandlerTouchEvent, + onReanimatedStateChange, + onReanimatedUpdateEvent, + onReanimatedTouchEvent, + onGestureHandlerAnimatedEvent, + }, + gestureRelations, + }), + [ + tag, + type, + config, onGestureHandlerStateChange, onGestureHandlerEvent, onGestureHandlerTouchEvent, @@ -107,7 +130,7 @@ export function useGesture( onReanimatedUpdateEvent, onReanimatedTouchEvent, onGestureHandlerAnimatedEvent, - }, - gestureRelations, - }; + gestureRelations, + ] + ); }