React Native Drawer Layout
react-native-drawer-layout provides a foundational and highly customizable drawer component for React Native applications, allowing for swipeable side navigation panels. It is a standalone component often used as a building block for higher-level navigation solutions, such as the Drawer Navigator within the React Navigation ecosystem. The current stable version is 4.2.2. While this specific package doesn't show recent direct releases in the provided logs, it is part of the actively maintained React Navigation suite, which implies a consistent release cadence for the ecosystem. Key differentiators include its reliance on `react-native-reanimated` and `react-native-gesture-handler` for smooth, performant animations and gestures, offering a robust and highly configurable user experience compared to less performant JavaScript-based drawer implementations.
Common errors
-
Invariant Violation: `[...]. You must be inside a <NavigationContainer> to use hook useNavigation`
cause While `react-native-drawer-layout` is a standalone component, it is often used with React Navigation. If you are trying to use hooks like `useNavigation` within content rendered by `DrawerLayout` and it's not nested inside a `NavigationContainer`, this error will occur.fixEnsure your entire application or at least the section containing the `DrawerLayout` is wrapped within a `<NavigationContainer>` from `@react-navigation/native`. -
Animated module is not installed correctly. Please make sure that 'react-native-reanimated/plugin' is added to your babel.config.js.
cause `react-native-reanimated` (v2+) requires a Babel plugin for its Worklets API. This error indicates the plugin is missing or incorrectly configured in your Babel setup.fixAdd `plugins: ['react-native-reanimated/plugin']` to your `babel.config.js` file. Ensure `react-native-reanimated` is installed and rebuild your app (e.g., `npx react-native run-android` or `npm run ios`). -
Error: Reanimated 2 is not yet fully integrated in your app. Please make sure you've followed the installation instructions carefully.
cause This typically occurs if the native part of `react-native-reanimated` is not correctly linked or initialized, often due to missing steps in `MainActivity.java` (Android) or `AppDelegate.mm` (iOS), or not rebuilding native apps after installation.fixVerify that you've followed *all* manual installation steps for `react-native-reanimated` (v2+), especially the changes in `android/app/src/main/java/<your-app-name>/MainActivity.java` (if applicable) and `ios/<your-app-name>/AppDelegate.mm`. Then, clean your build caches and rebuild the native application (`npx react-native start --reset-cache`, `cd android && ./gradlew clean`, `cd ios && pod install && xcodebuild clean`). -
Unrecognized selector sent to instance ... (for `react-native-gesture-handler` related errors on iOS)
cause This error usually indicates that `react-native-gesture-handler`'s native modules are not correctly linked or initialized on iOS, typically from not adding the necessary import or method swizzling in `AppDelegate.mm` or `index.js`.fixEnsure you have added `import 'react-native-gesture-handler';` at the very top of your application's entry file (e.g., `index.js`). For older versions or specific configurations, also check `AppDelegate.mm` for `[RNGestureHandlerRootView install]` or similar setup.
Warnings
- breaking Major versions of `react-native-reanimated` and `react-native-gesture-handler` can introduce breaking changes in their APIs, which `react-native-drawer-layout` depends on. Ensure compatibility when upgrading these peer dependencies.
- gotcha Proper installation and linking of `react-native-reanimated` and `react-native-gesture-handler` are crucial. Missing steps (e.g., adding `react-native-reanimated/plugin` to `babel.config.js` or making specific `MainActivity.java`/`AppDelegate.mm` changes) will lead to runtime errors or crashes.
- deprecated The `onDrawerStateChange` prop has been removed in favor of more specific `onDrawerOpen` and `onDrawerClose` callbacks for clearer event handling.
Install
-
npm install react-native-drawer-layout -
yarn add react-native-drawer-layout -
pnpm add react-native-drawer-layout
Imports
- DrawerLayout
import { DrawerLayout } from 'react-native-drawer-layout'import DrawerLayout from 'react-native-drawer-layout'
- DrawerLayoutProps
import { DrawerLayoutProps } from 'react-native-drawer-layout'import type { DrawerLayoutProps } from 'react-native-drawer-layout' - useDrawerStatus
import useDrawerStatus from 'react-native-drawer-layout'
import { useDrawerStatus } from 'react-native-drawer-layout'
Quickstart
import React, { useRef, useState } from 'react';
import { Button, Text, View, StyleSheet } from 'react-native';
import DrawerLayout from 'react-native-drawer-layout';
const App = () => {
const drawerRef = useRef(null);
const [drawerPosition, setDrawerPosition] = useState<'left' | 'right'>('left');
const openDrawer = () => {
drawerRef.current?.openDrawer();
};
const closeDrawer = () => {
drawerRef.current?.closeDrawer();
};
const toggleDrawerPosition = () => {
setDrawerPosition(prev => (prev === 'left' ? 'right' : 'left'));
};
const renderDrawer = () => (
<View style={styles.drawerContainer}>
<Text style={styles.drawerText}>I am the drawer content!</Text>
<Button title="Close Drawer" onPress={closeDrawer} />
<Button title="Toggle Position" onPress={toggleDrawerPosition} />
</View>
);
return (
<DrawerLayout
ref={drawerRef}
drawerWidth={300}
drawerPosition={drawerPosition}
renderNavigationView={renderDrawer}
statusBarAnimation={'slide'}
style={styles.container}
>
<View style={styles.content}>
<Text style={styles.mainText}>Main Content Area</Text>
<Button title="Open Drawer" onPress={openDrawer} />
</View>
</DrawerLayout>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
content: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
mainText: {
fontSize: 24,
marginBottom: 20,
},
drawerContainer: {
flex: 1,
backgroundColor: '#fff',
paddingTop: 50,
paddingHorizontal: 20,
},
drawerText: {
fontSize: 20,
marginBottom: 20,
},
});
export default App;