From 48cb50c090201061ba926d1d8ae2cd12e28be34c Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Tue, 25 Nov 2025 15:37:56 +0100 Subject: [PATCH 1/6] useReanimatedEventsManager --- .../src/v3/detectors/NativeDetector.tsx | 23 +++----- .../detectors/useReanimatedEventsManager.ts | 58 +++++++++++++++++++ 2 files changed, 65 insertions(+), 16 deletions(-) create mode 100644 packages/react-native-gesture-handler/src/v3/detectors/useReanimatedEventsManager.ts diff --git a/packages/react-native-gesture-handler/src/v3/detectors/NativeDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/NativeDetector.tsx index bae409b602..587ba54816 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/NativeDetector.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/NativeDetector.tsx @@ -6,28 +6,31 @@ import { AnimatedNativeDetector, NativeDetectorProps, nativeDetectorStyles, - ReanimatedNativeDetector, } from './common'; +import { useReanimatedEventsManager } from './useReanimatedEventsManager'; export function NativeDetector({ gesture, children, }: NativeDetectorProps) { + // TODO: is it possible with useReanimatedEventsManager to handle both Animated and Reanimated at the same time? + const NativeDetectorComponent = gesture.config.dispatchesAnimatedEvents ? AnimatedNativeDetector - : gesture.config.shouldUseReanimatedDetector - ? ReanimatedNativeDetector - : HostGestureDetector; + : HostGestureDetector; ensureNativeDetectorComponent(NativeDetectorComponent); configureRelations(gesture); + // TODO: call useReanimatedEventsManager only when using Reanimated + const viewRef = useReanimatedEventsManager(gesture); const handlerTags = useMemo(() => { return isComposedGesture(gesture) ? gesture.tags : [gesture.tag]; }, [gesture]); return ( ({ gesture.detectorCallbacks.onGestureHandlerTouchEvent } // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types - onGestureHandlerReanimatedStateChange={ - gesture.detectorCallbacks.onReanimatedStateChange - } - // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types - onGestureHandlerReanimatedEvent={ - gesture.detectorCallbacks.onReanimatedUpdateEvent - } - // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types - onGestureHandlerReanimatedTouchEvent={ - gesture.detectorCallbacks.onReanimatedTouchEvent - } - // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types onGestureHandlerAnimatedEvent={ gesture.detectorCallbacks.onGestureHandlerAnimatedEvent } diff --git a/packages/react-native-gesture-handler/src/v3/detectors/useReanimatedEventsManager.ts b/packages/react-native-gesture-handler/src/v3/detectors/useReanimatedEventsManager.ts new file mode 100644 index 0000000000..4964278831 --- /dev/null +++ b/packages/react-native-gesture-handler/src/v3/detectors/useReanimatedEventsManager.ts @@ -0,0 +1,58 @@ +import { useEffect, useMemo, useRef } from 'react'; +import { Gesture } from '../types'; +import { findNodeHandle } from 'react-native'; +// TODO: import from reanimatedWrapper +import { NativeEventsManager } from 'react-native-reanimated/src/createAnimatedComponent/NativeEventsManager'; + +// TODO: web +export function useReanimatedEventsManager( + gesture: Gesture +) { + const prevProps = useRef(null); + const eventManager = useRef(null); + const viewRef = useRef(null); + + const reaProps = useMemo( + () => ({ + onGestureHandlerReanimatedStateChange: + gesture.detectorCallbacks.onReanimatedStateChange, + // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types + onGestureHandlerReanimatedEvent: + gesture.detectorCallbacks.onReanimatedUpdateEvent, + // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types + onGestureHandlerReanimatedTouchEvent: + gesture.detectorCallbacks.onReanimatedTouchEvent, + }), + [ + gesture.detectorCallbacks.onReanimatedStateChange, + gesture.detectorCallbacks.onReanimatedTouchEvent, + gesture.detectorCallbacks.onReanimatedUpdateEvent, + ] + ); + + useEffect(() => { + const nativeTag = findNodeHandle(viewRef.current) ?? -1; + viewRef.__nativeTag = nativeTag; + eventManager.current = new NativeEventsManager({ + props: reaProps, + _componentRef: viewRef, + getComponentViewTag: () => { + return nativeTag; + }, + }); + eventManager.current.attachEvents(); + + return () => { + eventManager.current.detachEvents(); + }; + }, []); + + useEffect(() => { + if (prevProps.current) { + eventManager.current.updateEvents(prevProps.current); + } + prevProps.current = reaProps; + }, [reaProps]); + + return viewRef; +} From 29b96ce719d0219dd16b7504fc0451505d59d079 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Fri, 28 Nov 2025 15:27:50 +0100 Subject: [PATCH 2/6] Move the event logic to `ReanimatedNativeDetector` add fallback --- .../handlers/gestures/reanimatedWrapper.ts | 11 +++ .../src/v3/detectors/HostGestureDetector.tsx | 1 + .../src/v3/detectors/NativeDetector.tsx | 23 +++-- .../v3/detectors/ReanimatedNativeDetector.tsx | 93 +++++++++++++++++++ .../ReanimatedNativeDetector.web.tsx | 5 + .../InterceptingGestureDetector.tsx | 2 +- .../src/v3/detectors/common.ts | 4 - .../detectors/useReanimatedEventsManager.ts | 58 ------------ 8 files changed, 127 insertions(+), 70 deletions(-) create mode 100644 packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx create mode 100644 packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.web.tsx delete mode 100644 packages/react-native-gesture-handler/src/v3/detectors/useReanimatedEventsManager.ts diff --git a/packages/react-native-gesture-handler/src/handlers/gestures/reanimatedWrapper.ts b/packages/react-native-gesture-handler/src/handlers/gestures/reanimatedWrapper.ts index a9767d6c7d..46204cde66 100644 --- a/packages/react-native-gesture-handler/src/handlers/gestures/reanimatedWrapper.ts +++ b/packages/react-native-gesture-handler/src/handlers/gestures/reanimatedWrapper.ts @@ -29,6 +29,16 @@ export type ReanimatedHandler = { context: ReanimatedContext; }; +export type NativeEventsManager = new (component: { + props: Record; + _componentRef: React.Ref; + getComponentViewTag: () => number; +}) => { + attachEvents: () => void; + detachEvents: () => void; + updateEvents: (prevProps: Record) => void; +}; + let Reanimated: | { default: { @@ -38,6 +48,7 @@ let Reanimated: options?: unknown ): ComponentClass

; }; + NativeEventsManager: NativeEventsManager; useHandler: ( handlers: GestureCallbacks ) => ReanimatedHandler; diff --git a/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.tsx index 5b91d456e2..e6a763b32d 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.tsx @@ -1,3 +1,4 @@ import RNGestureHandlerDetectorNativeComponent from '../../specs/RNGestureHandlerDetectorNativeComponent'; +export { NativeProps as RNGestureHandlerDetectorNativeComponentProps } from '../../specs/RNGestureHandlerDetectorNativeComponent'; const HostGestureDetector = RNGestureHandlerDetectorNativeComponent; export default HostGestureDetector; diff --git a/packages/react-native-gesture-handler/src/v3/detectors/NativeDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/NativeDetector.tsx index 587ba54816..1fdb907f5e 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/NativeDetector.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/NativeDetector.tsx @@ -7,30 +7,27 @@ import { NativeDetectorProps, nativeDetectorStyles, } from './common'; -import { useReanimatedEventsManager } from './useReanimatedEventsManager'; +import { ReanimatedNativeDetector } from './ReanimatedNativeDetector'; export function NativeDetector({ gesture, children, }: NativeDetectorProps) { - // TODO: is it possible with useReanimatedEventsManager to handle both Animated and Reanimated at the same time? - const NativeDetectorComponent = gesture.config.dispatchesAnimatedEvents ? AnimatedNativeDetector - : HostGestureDetector; + : gesture.config.shouldUseReanimatedDetector + ? ReanimatedNativeDetector + : HostGestureDetector; ensureNativeDetectorComponent(NativeDetectorComponent); configureRelations(gesture); - // TODO: call useReanimatedEventsManager only when using Reanimated - const viewRef = useReanimatedEventsManager(gesture); const handlerTags = useMemo(() => { return isComposedGesture(gesture) ? gesture.tags : [gesture.tag]; }, [gesture]); return ( ({ gesture.detectorCallbacks.onGestureHandlerTouchEvent } // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types + onGestureHandlerReanimatedStateChange={ + gesture.detectorCallbacks.onReanimatedStateChange + } + // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types + onGestureHandlerReanimatedEvent={ + gesture.detectorCallbacks.onReanimatedUpdateEvent + } + // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types + onGestureHandlerReanimatedTouchEvent={ + gesture.detectorCallbacks.onReanimatedTouchEvent + } + // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types onGestureHandlerAnimatedEvent={ gesture.detectorCallbacks.onGestureHandlerAnimatedEvent } diff --git a/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx new file mode 100644 index 0000000000..fe070e3eac --- /dev/null +++ b/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx @@ -0,0 +1,93 @@ +import { useEffect, useMemo, useRef } from 'react'; +import { + NativeEventsManager, + Reanimated, +} from '../../handlers/gestures/reanimatedWrapper'; +import HostGestureDetector, { + type RNGestureHandlerDetectorNativeComponentProps, +} from './HostGestureDetector'; +import { findNodeHandle } from 'react-native'; + +let NativeEventsManagerImpl = Reanimated?.NativeEventsManager; + +if (!NativeEventsManagerImpl) { + // Fallback to empty object when Reanimated or NativeEventsManager is not available + try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + NativeEventsManagerImpl = + // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access + require('react-native-reanimated/src/createAnimatedComponent/NativeEventsManager').NativeEventsManager; + } catch { + // fail silently + } +} + +type WorkletProps = Pick< + RNGestureHandlerDetectorNativeComponentProps, + | 'onGestureHandlerReanimatedStateChange' + | 'onGestureHandlerReanimatedEvent' + | 'onGestureHandlerReanimatedTouchEvent' +>; + +function LeanReanimatedNativeDetector( + props: RNGestureHandlerDetectorNativeComponentProps +) { + const prevProps = useRef(null); + const eventManager = useRef | null>(null); + const viewRef = useRef(null); + + const { + onGestureHandlerReanimatedStateChange, + onGestureHandlerReanimatedEvent, + onGestureHandlerReanimatedTouchEvent, + ...restProps + } = props; + + const reaProps: WorkletProps = useMemo( + () => ({ + onGestureHandlerReanimatedStateChange, + // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types + onGestureHandlerReanimatedEvent, + // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types + onGestureHandlerReanimatedTouchEvent, + }), + [ + onGestureHandlerReanimatedEvent, + onGestureHandlerReanimatedStateChange, + onGestureHandlerReanimatedTouchEvent, + ] + ); + + useEffect(() => { + const nativeTag = findNodeHandle(viewRef.current) ?? -1; + // @ts-expect-error Reanimated expects __nativeTag to be present on the ref + viewRef.__nativeTag = nativeTag; + // @ts-expect-error NativeEventsManager should be defined here, if it isn't, we should + // go the fallback way and use Reanimated's createAnimatedComponent + eventManager.current = new NativeEventsManagerImpl({ + props: reaProps, + _componentRef: viewRef, + getComponentViewTag: () => { + return nativeTag; + }, + }); + eventManager.current.attachEvents(); + + return () => { + eventManager.current?.detachEvents(); + }; + }, []); + + useEffect(() => { + if (prevProps.current) { + eventManager.current?.updateEvents(prevProps.current); + } + prevProps.current = reaProps; + }, [reaProps]); + + return ; +} + +export const ReanimatedNativeDetector = NativeEventsManagerImpl + ? LeanReanimatedNativeDetector + : Reanimated?.default.createAnimatedComponent(HostGestureDetector); diff --git a/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.web.tsx b/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.web.tsx new file mode 100644 index 0000000000..2036bce696 --- /dev/null +++ b/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.web.tsx @@ -0,0 +1,5 @@ +import { Reanimated } from '../../handlers/gestures/reanimatedWrapper'; +import HostGestureDetector from './HostGestureDetector'; + +export const ReanimatedNativeDetector = + Reanimated?.default.createAnimatedComponent(HostGestureDetector); diff --git a/packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/InterceptingGestureDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/InterceptingGestureDetector.tsx index 94d16ac136..8b4fe6ad25 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/InterceptingGestureDetector.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/InterceptingGestureDetector.tsx @@ -17,10 +17,10 @@ import { AnimatedNativeDetector, InterceptingGestureDetectorProps, nativeDetectorStyles, - ReanimatedNativeDetector, } from '../common'; import { tagMessage } from '../../../utils'; import { useEnsureGestureHandlerRootView } from '../useEnsureGestureHandlerRootView'; +import { ReanimatedNativeDetector } from '../ReanimatedNativeDetector'; interface VirtualChildrenForNative { viewTag: number; diff --git a/packages/react-native-gesture-handler/src/v3/detectors/common.ts b/packages/react-native-gesture-handler/src/v3/detectors/common.ts index ae1560381e..a31d5b5ba0 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/common.ts +++ b/packages/react-native-gesture-handler/src/v3/detectors/common.ts @@ -1,6 +1,5 @@ import React from 'react'; import { Gesture } from '../types'; -import { Reanimated } from '../../handlers/gestures/reanimatedWrapper'; import { Animated, StyleSheet } from 'react-native'; import HostGestureDetector from './HostGestureDetector'; import { GestureDetectorProps as LegacyDetectorProps } from '../../handlers/gestures/GestureDetector'; @@ -23,9 +22,6 @@ export type GestureDetectorProps = export const AnimatedNativeDetector = Animated.createAnimatedComponent(HostGestureDetector); -export const ReanimatedNativeDetector = - Reanimated?.default.createAnimatedComponent(HostGestureDetector); - export const nativeDetectorStyles = StyleSheet.create({ detector: { display: 'contents', diff --git a/packages/react-native-gesture-handler/src/v3/detectors/useReanimatedEventsManager.ts b/packages/react-native-gesture-handler/src/v3/detectors/useReanimatedEventsManager.ts deleted file mode 100644 index 4964278831..0000000000 --- a/packages/react-native-gesture-handler/src/v3/detectors/useReanimatedEventsManager.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { useEffect, useMemo, useRef } from 'react'; -import { Gesture } from '../types'; -import { findNodeHandle } from 'react-native'; -// TODO: import from reanimatedWrapper -import { NativeEventsManager } from 'react-native-reanimated/src/createAnimatedComponent/NativeEventsManager'; - -// TODO: web -export function useReanimatedEventsManager( - gesture: Gesture -) { - const prevProps = useRef(null); - const eventManager = useRef(null); - const viewRef = useRef(null); - - const reaProps = useMemo( - () => ({ - onGestureHandlerReanimatedStateChange: - gesture.detectorCallbacks.onReanimatedStateChange, - // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types - onGestureHandlerReanimatedEvent: - gesture.detectorCallbacks.onReanimatedUpdateEvent, - // @ts-ignore This is a type mismatch between RNGH types and RN Codegen types - onGestureHandlerReanimatedTouchEvent: - gesture.detectorCallbacks.onReanimatedTouchEvent, - }), - [ - gesture.detectorCallbacks.onReanimatedStateChange, - gesture.detectorCallbacks.onReanimatedTouchEvent, - gesture.detectorCallbacks.onReanimatedUpdateEvent, - ] - ); - - useEffect(() => { - const nativeTag = findNodeHandle(viewRef.current) ?? -1; - viewRef.__nativeTag = nativeTag; - eventManager.current = new NativeEventsManager({ - props: reaProps, - _componentRef: viewRef, - getComponentViewTag: () => { - return nativeTag; - }, - }); - eventManager.current.attachEvents(); - - return () => { - eventManager.current.detachEvents(); - }; - }, []); - - useEffect(() => { - if (prevProps.current) { - eventManager.current.updateEvents(prevProps.current); - } - prevProps.current = reaProps; - }, [reaProps]); - - return viewRef; -} From b2f3faaba8c6c0809e06af36de97dcc762977c58 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Fri, 28 Nov 2025 15:52:32 +0100 Subject: [PATCH 3/6] Backwards compatibility --- .../src/handlers/gestures/reanimatedWrapper.ts | 3 +++ .../src/v3/detectors/ReanimatedNativeDetector.tsx | 1 + 2 files changed, 4 insertions(+) diff --git a/packages/react-native-gesture-handler/src/handlers/gestures/reanimatedWrapper.ts b/packages/react-native-gesture-handler/src/handlers/gestures/reanimatedWrapper.ts index 46204cde66..9044a8a3df 100644 --- a/packages/react-native-gesture-handler/src/handlers/gestures/reanimatedWrapper.ts +++ b/packages/react-native-gesture-handler/src/handlers/gestures/reanimatedWrapper.ts @@ -32,6 +32,9 @@ export type ReanimatedHandler = { export type NativeEventsManager = new (component: { props: Record; _componentRef: React.Ref; + // Removed in https://github.com/software-mansion/react-native-reanimated/pull/6736 + // but we likely want to keep it for compatibility with older Reanimated versions + _componentViewTag: number; getComponentViewTag: () => number; }) => { attachEvents: () => void; diff --git a/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx index fe070e3eac..3232791e35 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx @@ -67,6 +67,7 @@ function LeanReanimatedNativeDetector( eventManager.current = new NativeEventsManagerImpl({ props: reaProps, _componentRef: viewRef, + _componentViewTag: nativeTag, getComponentViewTag: () => { return nativeTag; }, From 40503cbb3fed0834f4914f58ebd8650f24a36603 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Mon, 1 Dec 2025 09:21:07 +0100 Subject: [PATCH 4/6] Update packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michał Bert <63123542+m-bert@users.noreply.github.com> --- .../src/v3/detectors/HostGestureDetector.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.tsx index e6a763b32d..961acece25 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.tsx @@ -1,4 +1,4 @@ import RNGestureHandlerDetectorNativeComponent from '../../specs/RNGestureHandlerDetectorNativeComponent'; -export { NativeProps as RNGestureHandlerDetectorNativeComponentProps } from '../../specs/RNGestureHandlerDetectorNativeComponent'; +export type { NativeProps as RNGestureHandlerDetectorNativeComponentProps } from '../../specs/RNGestureHandlerDetectorNativeComponent'; const HostGestureDetector = RNGestureHandlerDetectorNativeComponent; export default HostGestureDetector; From 1b8c9ee51b2c14670070da9394661bf0bb93f33a Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Mon, 1 Dec 2025 09:21:14 +0100 Subject: [PATCH 5/6] Update packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michał Bert <63123542+m-bert@users.noreply.github.com> --- .../src/v3/detectors/ReanimatedNativeDetector.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx index 3232791e35..15aabfa64c 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx @@ -68,9 +68,7 @@ function LeanReanimatedNativeDetector( props: reaProps, _componentRef: viewRef, _componentViewTag: nativeTag, - getComponentViewTag: () => { - return nativeTag; - }, + getComponentViewTag: () => nativeTag, }); eventManager.current.attachEvents(); From df7eaac45bf4de25b968a6a16dbf87bf958bd6fa Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Mon, 1 Dec 2025 09:24:04 +0100 Subject: [PATCH 6/6] Update comment --- .../src/v3/detectors/ReanimatedNativeDetector.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx index 15aabfa64c..ec84030cf4 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx @@ -11,7 +11,10 @@ import { findNodeHandle } from 'react-native'; let NativeEventsManagerImpl = Reanimated?.NativeEventsManager; if (!NativeEventsManagerImpl) { - // Fallback to empty object when Reanimated or NativeEventsManager is not available + // When Reanimated.NativeEventsManager is undefined, it may be that an older + // Reanimated version is used which doesn't export NativeEventsManager, or + // Reanimated is not installed at all. For the older versions, try to import + // NativeEventsManager by a subpath. Otherwise, it will stay undefined. try { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment NativeEventsManagerImpl =