Drawer Navigator
React Native drawer navigator: side menu with React Navigation. Setup, custom content, and the gestures users expect.
React Native — Drawer
EXAMPLE
# ===== Install =====
npm install @react-navigation/native @react-navigation/drawer
npm install react-native-screens react-native-safe-area-context react-native-gesture-handler react-native-reanimated
# Expo:
npx expo install react-native-screens react-native-safe-area-context react-native-gesture-handler react-native-reanimated
# Wrap your app root in GestureHandlerRootView:
import { GestureHandlerRootView } from 'react-native-gesture-handler';
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<NavigationContainer>
<RootNavigator />
</NavigationContainer>
</GestureHandlerRootView>
);
}
# ===== Basic drawer =====
import { createDrawerNavigator } from '@react-navigation/drawer';
const Drawer = createDrawerNavigator();
function RootNavigator() {
return (
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Settings" component={SettingsScreen} />
<Drawer.Screen name="About" component={AboutScreen} />
</Drawer.Navigator>
);
}
# ===== Open from a screen =====
function HomeScreen({ navigation }) {
return (
<View>
<Button title="Menu" onPress={() => navigation.openDrawer()} />
<Button title="Settings" onPress={() => navigation.navigate('Settings')} />
</View>
);
}
# ===== Drawer options =====
<Drawer.Screen
name="Settings"
component={SettingsScreen}
options={{
title: 'Settings',
drawerIcon: ({ color, size }) => <Icon name="cog" color={color} size={size} />,
drawerActiveTintColor: '#2563eb',
drawerLabelStyle: { fontWeight: '600' },
}}
/>
# ===== Custom drawer content =====
import { DrawerContentScrollView, DrawerItemList, DrawerItem } from '@react-navigation/drawer';
function CustomDrawer(props) {
return (
<DrawerContentScrollView {...props}>
<View style={{ padding: 16 }}>
<Image source={{ uri: user.avatar }} style={{ width: 60, height: 60, borderRadius: 30 }} />
<Text style={{ fontSize: 18, fontWeight: '600' }}>{user.name}</Text>
</View>
<DrawerItemList {...props} />
<DrawerItem label="Sign out" onPress={signOut} />
</DrawerContentScrollView>
);
}
<Drawer.Navigator drawerContent={(props) => <CustomDrawer {...props} />}>
...
</Drawer.Navigator>
# ===== Drawer styling =====
<Drawer.Navigator screenOptions={{
drawerStyle: { backgroundColor: '#0f172a', width: 280 },
drawerActiveTintColor: '#60a5fa',
drawerInactiveTintColor: '#cbd5e1',
headerStyle: { backgroundColor: '#0f172a' },
headerTintColor: '#fff',
drawerType: 'slide', // 'front' (default), 'back', 'slide', 'permanent'
drawerPosition: 'left', // or 'right'
}}>
# ===== When NOT to use a drawer =====
// - Apps with 3 top-level destinations -> use tabs instead
// - Apps with mostly read-only content -> top nav often enough
// - Modern mobile design leans toward bottom tabs + stack; drawers for secondary nav
# ===== Patterns to internalise =====
// - GestureHandlerRootView at the root (mandatory)
// - Custom drawerContent for user info + branded layout
// - 'drawerType: permanent' for tablet / web layouts
// - drawerStatusBarAnimation for smooth status bar transitions
# ===== Pitfalls =====
// - Forgetting GestureHandlerRootView -> gestures break
// - Drawer + tabs without thinking about hierarchy
// - Too many top-level destinations (use tabs instead)
// - Inconsistent header behaviour between drawer + stack
Why it matters
React Navigations drawer navigator gives you a side menu in three calls. Install the deps, wrap in GestureHandlerRootView, define screens, optionally customise drawerContent. Reach for it on apps with many top-level destinations; modern design often prefers tabs + stack for primary nav.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
import { createDrawerNavigator } from '@react-navigation/drawer';
const Drawer = createDrawerNavigator();
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
</Drawer.Navigator>
Try it Yourself »
Discussion
Loading…