From ddb3e4dfdf1d40cbc568ea915c53ae7ea630625e Mon Sep 17 00:00:00 2001 From: Mathieu Acthernoene Date: Fri, 8 May 2026 15:09:49 +0200 Subject: [PATCH 1/5] Fix `RNRenderer` import for React Native 0.86+ --- .../src/RNRenderer.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/react-native-gesture-handler/src/RNRenderer.ts b/packages/react-native-gesture-handler/src/RNRenderer.ts index 7a585b64c0..a5ed37150b 100644 --- a/packages/react-native-gesture-handler/src/RNRenderer.ts +++ b/packages/react-native-gesture-handler/src/RNRenderer.ts @@ -1,3 +1,16 @@ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-nocheck -export { default as RNRenderer } from 'react-native/Libraries/Renderer/shims/ReactNative'; +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +let RNRenderer: any; + +try { + // React Native >= 0.86 removed `Libraries/Renderer/shims/ReactNative`. + RNRenderer = require('react-native/Libraries/ReactNative/RendererProxy'); +} catch (e) { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const shim = require('react-native/Libraries/Renderer/shims/ReactNative'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + RNRenderer = shim.default; +} + +export { RNRenderer }; From 0cffecf900770845edcfa30a8bd7ea7c59187948 Mon Sep 17 00:00:00 2001 From: Mathieu Acthernoene Date: Fri, 8 May 2026 16:57:38 +0200 Subject: [PATCH 2/5] Copilot review --- .../src/RNRenderer.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/react-native-gesture-handler/src/RNRenderer.ts b/packages/react-native-gesture-handler/src/RNRenderer.ts index a5ed37150b..16a590d31a 100644 --- a/packages/react-native-gesture-handler/src/RNRenderer.ts +++ b/packages/react-native-gesture-handler/src/RNRenderer.ts @@ -1,16 +1,15 @@ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any -let RNRenderer: any; +let rendererModule: any; try { // React Native >= 0.86 removed `Libraries/Renderer/shims/ReactNative`. - RNRenderer = require('react-native/Libraries/ReactNative/RendererProxy'); -} catch (e) { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const shim = require('react-native/Libraries/Renderer/shims/ReactNative'); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - RNRenderer = shim.default; + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + rendererModule = require('react-native/Libraries/ReactNative/RendererProxy'); +} catch { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + rendererModule = require('react-native/Libraries/Renderer/shims/ReactNative'); } +// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access +const RNRenderer = rendererModule.default ?? rendererModule; export { RNRenderer }; From 0d48ca9b2e88407272bb7219c3c2d3b94ffd6df4 Mon Sep 17 00:00:00 2001 From: Mathieu Acthernoene Date: Fri, 8 May 2026 16:57:56 +0200 Subject: [PATCH 3/5] remove extra space --- packages/react-native-gesture-handler/src/RNRenderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native-gesture-handler/src/RNRenderer.ts b/packages/react-native-gesture-handler/src/RNRenderer.ts index 16a590d31a..9ecf4ceb77 100644 --- a/packages/react-native-gesture-handler/src/RNRenderer.ts +++ b/packages/react-native-gesture-handler/src/RNRenderer.ts @@ -10,6 +10,6 @@ try { rendererModule = require('react-native/Libraries/Renderer/shims/ReactNative'); } -// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access +// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access const RNRenderer = rendererModule.default ?? rendererModule; export { RNRenderer }; From adcf1d0ea4137ec846176aa6fc0699caa4db334c Mon Sep 17 00:00:00 2001 From: Mathieu Acthernoene Date: Fri, 8 May 2026 16:59:35 +0200 Subject: [PATCH 4/5] use export const --- packages/react-native-gesture-handler/src/RNRenderer.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/react-native-gesture-handler/src/RNRenderer.ts b/packages/react-native-gesture-handler/src/RNRenderer.ts index 9ecf4ceb77..4885edb211 100644 --- a/packages/react-native-gesture-handler/src/RNRenderer.ts +++ b/packages/react-native-gesture-handler/src/RNRenderer.ts @@ -11,5 +11,4 @@ try { } // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access -const RNRenderer = rendererModule.default ?? rendererModule; -export { RNRenderer }; +export const RNRenderer = rendererModule.default ?? rendererModule; From 9ce800dcce023094aa6a8a9f84ebab683185bb18 Mon Sep 17 00:00:00 2001 From: Mathieu Acthernoene Date: Mon, 11 May 2026 11:44:41 +0200 Subject: [PATCH 5/5] Remove validateDetectorChildren --- .../src/RNRenderer.ts | 14 ----- .../src/RNRenderer.web.ts | 3 -- .../GestureDetector/useDetectorUpdater.ts | 3 +- .../gestures/GestureDetector/utils.ts | 52 ------------------- 4 files changed, 1 insertion(+), 71 deletions(-) delete mode 100644 packages/react-native-gesture-handler/src/RNRenderer.ts delete mode 100644 packages/react-native-gesture-handler/src/RNRenderer.web.ts diff --git a/packages/react-native-gesture-handler/src/RNRenderer.ts b/packages/react-native-gesture-handler/src/RNRenderer.ts deleted file mode 100644 index 4885edb211..0000000000 --- a/packages/react-native-gesture-handler/src/RNRenderer.ts +++ /dev/null @@ -1,14 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -let rendererModule: any; - -try { - // React Native >= 0.86 removed `Libraries/Renderer/shims/ReactNative`. - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - rendererModule = require('react-native/Libraries/ReactNative/RendererProxy'); -} catch { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - rendererModule = require('react-native/Libraries/Renderer/shims/ReactNative'); -} - -// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access -export const RNRenderer = rendererModule.default ?? rendererModule; diff --git a/packages/react-native-gesture-handler/src/RNRenderer.web.ts b/packages/react-native-gesture-handler/src/RNRenderer.web.ts deleted file mode 100644 index d46b825958..0000000000 --- a/packages/react-native-gesture-handler/src/RNRenderer.web.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const RNRenderer = { - findHostInstance_DEPRECATED: (_ref: any) => null, -}; diff --git a/packages/react-native-gesture-handler/src/handlers/gestures/GestureDetector/useDetectorUpdater.ts b/packages/react-native-gesture-handler/src/handlers/gestures/GestureDetector/useDetectorUpdater.ts index d15877fd5d..2b3857a4b5 100644 --- a/packages/react-native-gesture-handler/src/handlers/gestures/GestureDetector/useDetectorUpdater.ts +++ b/packages/react-native-gesture-handler/src/handlers/gestures/GestureDetector/useDetectorUpdater.ts @@ -10,7 +10,7 @@ import { dropHandlers } from './dropHandlers'; import { needsToReattach } from './needsToReattach'; import type { AttachedGestureState, GestureDetectorState } from './types'; import { updateHandlers } from './updateHandlers'; -import { useForceRender, validateDetectorChildren } from './utils'; +import { useForceRender } from './utils'; // Returns a function that's responsible for updating the attached gestures // If the view has changed, it will reattach the handlers to the new view @@ -34,7 +34,6 @@ export function useDetectorUpdater( didUnderlyingViewChange || needsToReattach(preparedGesture, gesturesToAttach) ) { - validateDetectorChildren(state.viewRef); dropHandlers(preparedGesture); attachHandlers({ preparedGesture, diff --git a/packages/react-native-gesture-handler/src/handlers/gestures/GestureDetector/utils.ts b/packages/react-native-gesture-handler/src/handlers/gestures/GestureDetector/utils.ts index cb13c24c9b..5b5f36c97f 100644 --- a/packages/react-native-gesture-handler/src/handlers/gestures/GestureDetector/utils.ts +++ b/packages/react-native-gesture-handler/src/handlers/gestures/GestureDetector/utils.ts @@ -1,7 +1,5 @@ import { useCallback, useRef, useState } from 'react'; -import { Platform } from 'react-native'; -import { RNRenderer } from '../../../RNRenderer'; import { isTestEnv, tagMessage } from '../../../utils'; import type { GestureHandlerNativeEvent, @@ -124,56 +122,6 @@ export function checkGestureCallbacksForWorklets(gesture: GestureType) { } } -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function validateDetectorChildren(ref: any) { - // Finds the first native view under the Wrap component and traverses the fiber tree upwards - // to check whether there is more than one native view as a pseudo-direct child of GestureDetector - // i.e. this is not ok: - // Wrap - // | - // / \ - // / \ - // / \ - // / \ - // NativeView NativeView - // - // but this is fine: - // Wrap - // | - // NativeView - // | - // / \ - // / \ - // / \ - // / \ - // NativeView NativeView - if (__DEV__ && Platform.OS !== 'web') { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const wrapType = - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - ref._reactInternals.elementType; - - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - let instance = - RNRenderer.findHostInstance_DEPRECATED( - ref - )._internalFiberInstanceHandleDEV; - - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - while (instance && instance.elementType !== wrapType) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - if (instance.sibling) { - throw new Error( - 'GestureDetector has more than one native view as its children. This can happen if you are using a custom component that renders multiple views, like React.Fragment. You should wrap content of GestureDetector with a or .' - ); - } - - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access - instance = instance.return; - } - } -} - export function useForceRender() { const [renderState, setRenderState] = useState(false); const forceRender = useCallback(() => {