Skip to content

Commit a95f00f

Browse files
authored
Resolve DrawerLayoutAndroid lazily to avoid RN deprecation warning on import (#4493)
## Description Since React Native 0.87 the `DrawerLayoutAndroid` export is a getter that logs `DrawerLayoutAndroid is deprecated and will be removed in a future release` through `warnOnce` on first access. `GestureComponents.tsx` imported it at module level to build `LegacyDrawerLayoutAndroid`, so every app that imports gesture-handler saw the warning at startup, even if it never rendered a drawer. `LegacyDrawerLayoutAndroid` now wraps a small component that reads `DrawerLayoutAndroid` from `react-native` on first render and caches it in a module-level variable, so the warning appears only for apps that actually render the deprecated wrapper. The read uses `require` rather than `import * as RN`, because Metro's `experimentalImportSupport` (enabled by default in Expo) copies every export eagerly and would trigger all of RN's deprecation getters at once. Fixes #4491 ## Test plan - `yarn ts-check`, `yarn test` and `yarn lint:js` in the package - `yarn ts-check` in `apps/basic-example` - `basic-example` on Android: no deprecation warning at startup, one warning when opening the `Drawer Layout` screen; open/close via edge swipe and via ref buttons, drawer callbacks and `RectButton` presses work
1 parent e9ff66f commit a95f00f

1 file changed

Lines changed: 30 additions & 4 deletions

File tree

‎packages/react-native-gesture-handler/src/components/GestureComponents.tsx‎

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import type { PropsWithChildren, ReactElement } from 'react';
22
import * as React from 'react';
33
import type {
4+
DrawerLayoutAndroid as RNDrawerLayoutAndroid,
45
DrawerLayoutAndroidProps as RNDrawerLayoutAndroidProps,
56
FlatListProps as RNFlatListProps,
67
ScrollViewProps as RNScrollViewProps,
78
SwitchProps as RNSwitchProps,
89
TextInputProps as RNTextInputProps,
910
} from 'react-native';
1011
import {
11-
DrawerLayoutAndroid as RNDrawerLayoutAndroid,
1212
FlatList as RNFlatList,
1313
RefreshControl as RNRefreshControl,
1414
ScrollView as RNScrollView,
@@ -96,18 +96,44 @@ export const LegacyTextInput =
9696
// eslint-disable-next-line @typescript-eslint/no-redeclare
9797
export type LegacyTextInput = typeof LegacyTextInput & RNTextInput;
9898

99+
// RN's `DrawerLayoutAndroid` export is a getter that logs a deprecation
100+
// warning on access, so resolve it on first render instead of module load.
101+
// `require` is used on purpose: `import * as RN` would read every export
102+
// eagerly under Metro's `experimentalImportSupport`.
103+
let DrawerLayoutAndroidImpl: typeof RNDrawerLayoutAndroid | undefined;
104+
105+
const LazyDrawerLayoutAndroid = (
106+
props: PropsWithChildren<RNDrawerLayoutAndroidProps> & {
107+
ref?: React.Ref<React.ComponentRef<typeof RNDrawerLayoutAndroid> | null>;
108+
}
109+
) => {
110+
if (!DrawerLayoutAndroidImpl) {
111+
// eslint-disable-next-line @typescript-eslint/no-var-requires
112+
const { DrawerLayoutAndroid } = require('react-native') as {
113+
DrawerLayoutAndroid: typeof RNDrawerLayoutAndroid;
114+
};
115+
DrawerLayoutAndroidImpl = DrawerLayoutAndroid;
116+
}
117+
return <DrawerLayoutAndroidImpl {...props} />;
118+
};
119+
LazyDrawerLayoutAndroid.displayName = 'DrawerLayoutAndroid';
120+
99121
/**
100122
* @deprecated use `DrawerLayoutAndroid` instead
101123
*/
102124
export const LegacyDrawerLayoutAndroid: React.ComponentType<
103-
PropsWithChildren<RNDrawerLayoutAndroidProps> & NativeViewGestureHandlerProps
125+
PropsWithChildren<RNDrawerLayoutAndroidProps> &
126+
NativeViewGestureHandlerProps & {
127+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
128+
ref?: React.Ref<React.ComponentType<any> | null>;
129+
}
104130
> = createNativeWrapper<PropsWithChildren<RNDrawerLayoutAndroidProps>>(
105-
RNDrawerLayoutAndroid,
131+
LazyDrawerLayoutAndroid,
106132
{ disallowInterruption: true }
107133
);
108134
// eslint-disable-next-line @typescript-eslint/no-redeclare
109135
export type LegacyDrawerLayoutAndroid = typeof LegacyDrawerLayoutAndroid &
110-
RNDrawerLayoutAndroid;
136+
React.ComponentRef<typeof RNDrawerLayoutAndroid>;
111137

112138
/**
113139
* @deprecated use `FlatList` instead

0 commit comments

Comments
 (0)