Skip to content

Commit e1af85b

Browse files
committed
Update docs for multiple drawers
1 parent c8bb6ca commit e1af85b

File tree

4 files changed

+288
-16
lines changed

4 files changed

+288
-16
lines changed

versioned_docs/version-6.x/drawer-navigator.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Drawer Navigator renders a navigation drawer on the side of the screen which can
1212
</video>
1313
</div>
1414

15-
This wraps [`react-native-drawer-layout`](drawer-layout.md). If you want to use the tab view without React Navigation integration, use the library directly instead.
15+
This wraps [`react-native-drawer-layout`](drawer-layout.md). If you want to use the drawer without React Navigation integration, use the library directly instead.
1616

1717
## Installation
1818

versioned_docs/version-6.x/multiple-drawers.md

+143-7
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,144 @@ title: Multiple drawers
44
sidebar_label: Multiple drawers
55
---
66

7-
Sometimes we want to have multiple drawers on the same screen: one on the left and one on the right. This can be achieved by [nesting](nesting-navigators.md) 2 [drawer navigators](drawer-navigator.md).
7+
Sometimes we want to have multiple drawers on the same screen: one on the left and one on the right. This can be achieved in 2 ways:
8+
9+
1. By using [`react-native-drawer-layout`](drawer-layout.md) directly (Recommended).
10+
2. By [nesting](nesting-navigators.md) 2 [drawer navigators](drawer-navigator.md).
11+
12+
## Using `react-native-drawer-layout`
13+
14+
When we have multiple drawers, only one of them shows the list of screens. The second drawer may often be used to show some additional information such as the list of users etc.
15+
16+
In such cases, we can use [`react-native-drawer-layout`](drawer-layout.md) directly to render the second drawer. The drawer navigator will be used to render the first drawer and can be nested inside the second drawer:
17+
18+
```js
19+
import * as React from 'react';
20+
import { Button, View } from 'react-native';
21+
import { Drawer } from 'react-native-drawer-layout';
22+
import { createDrawerNavigator } from '@react-navigation/drawer';
23+
24+
function HomeScreen({ navigation }) {
25+
return (
26+
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
27+
<Button onPress={() => navigation.openDrawer()} title="Open drawer" />
28+
</View>
29+
);
30+
}
31+
32+
const LeftDrawer = createDrawerNavigator();
33+
34+
const LeftDrawerScreen = () => {
35+
return (
36+
<LeftDrawer.Navigator screenOptions={{ drawerPosition: 'left' }}>
37+
<LeftDrawer.Screen name="Home" component={HomeScreen} />
38+
</LeftDrawer.Navigator>
39+
);
40+
};
41+
42+
function RightDrawerScreen() {
43+
const [letDrawerOpen, setLeftDrawerOpen] = React.useState(false);
44+
45+
return (
46+
<Drawer
47+
open={rightDrawerOpen}
48+
onOpen={() => setRightDrawerOpen(true)}
49+
onClose={() => setRightDrawerOpen(false)}
50+
drawerPosition="right"
51+
renderDrawerContent={() => <>{/* Right drawer content */}</>}
52+
>
53+
<LeftDrawerScreen />
54+
</Drawer>
55+
);
56+
}
57+
58+
export default function App() {
59+
return (
60+
<NavigationContainer>
61+
<RightDrawerScreen />
62+
</NavigationContainer>
63+
);
64+
}
65+
```
66+
67+
But there is one problem. When we call `navigation.openDrawer()` in our `HomeScreen`, it always opens the left drawer. We don't have access to the right drawer via the `navigation` prop since it's not a navigator.
68+
69+
To solve this, we need to use context API to pass down a function to control the right drawer:
70+
71+
```js
72+
import * as React from 'react';
73+
import { Button, View } from 'react-native';
74+
import { Drawer } from 'react-native-drawer-layout';
75+
import { createDrawerNavigator } from '@react-navigation/drawer';
76+
77+
const RightDrawerContext = React.createContext();
78+
79+
function HomeScreen({ navigation }) {
80+
const { openRightDrawer } = React.useContext(RightDrawerContext);
81+
82+
return (
83+
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
84+
<Button
85+
onPress={() => navigation.openDrawer()}
86+
title="Open left drawer"
87+
/>
88+
<Button onPress={() => openRightDrawer()} title="Open right drawer" />
89+
</View>
90+
);
91+
}
92+
93+
const LeftDrawer = createDrawerNavigator();
94+
95+
const LeftDrawerScreen = () => {
96+
return (
97+
<LeftDrawer.Navigator screenOptions={{ drawerPosition: 'left' }}>
98+
<LeftDrawer.Screen name="Home" component={HomeScreen} />
99+
</LeftDrawer.Navigator>
100+
);
101+
};
102+
103+
function RightDrawerScreen() {
104+
const [letDrawerOpen, setLeftDrawerOpen] = React.useState(false);
105+
106+
const value = React.useMemo(
107+
() => ({
108+
openRightDrawer: () => setRightDrawerOpen(true),
109+
closeRightDrawer: () => setRightDrawerOpen(false),
110+
}),
111+
[]
112+
);
113+
114+
return (
115+
<Drawer
116+
open={rightDrawerOpen}
117+
onOpen={() => setRightDrawerOpen(true)}
118+
onClose={() => setRightDrawerOpen(false)}
119+
drawerPosition="right"
120+
renderDrawerContent={() => <>{/* Right drawer content */}</>}
121+
>
122+
<RightDrawerContext.Provider value={value}>
123+
<LeftDrawerScreen />
124+
</RightDrawerContext.Provider>
125+
</Drawer>
126+
);
127+
}
128+
129+
export default function App() {
130+
return (
131+
<NavigationContainer>
132+
<RightDrawerScreen />
133+
</NavigationContainer>
134+
);
135+
}
136+
```
137+
138+
Here, we are using the `RightDrawerContext` to pass down the `openRightDrawer` function to the `HomeScreen`. Then we use `openRightDrawer` to open the right drawer.
8139

9140
## Nesting 2 drawer navigators
10141

11-
Here we have 2 drawers nested inside each other, one is positioned on left and the other on the right:
142+
An alternative approach is to nest 2 [drawer navigators](drawer-navigator.md) inside each other. This is not recommended since it requires creating an additional screen and more nesting - which can make navigating and type checking more verbose. But this can be useful if both navigators include multiple screens.
143+
144+
Here we have 2 drawer navigators nested inside each other, one is positioned on left and the other on the right:
12145

13146
<samp id="multiple-drawers-issue"/>
14147

@@ -109,7 +242,8 @@ function LeftDrawerScreen() {
109242
return (
110243
<LeftDrawer.Navigator
111244
id="LeftDrawer"
112-
screenOptions={{ drawerPosition: 'left' }}>
245+
screenOptions={{ drawerPosition: 'left' }}
246+
>
113247
<LeftDrawer.Screen name="Home" component={HomeScreen} />
114248
</LeftDrawer.Navigator>
115249
);
@@ -125,7 +259,8 @@ function RightDrawerScreen() {
125259
screenOptions={{
126260
drawerPosition: 'right',
127261
headerShown: false,
128-
}}>
262+
}}
263+
>
129264
<RightDrawer.Screen name="HomeDrawer" component={LeftDrawerScreen} />
130265
</RightDrawer.Navigator>
131266
);
@@ -138,12 +273,13 @@ export default function App() {
138273
</NavigationContainer>
139274
);
140275
}
141-
142276
```
143277

144278
Here, we are passing `"LeftDrawer"` and `"RightDrawer"` strings (you can use any string here) in the `id` prop of the drawer navigators. Then we use `navigation.getParent('LeftDrawer').openDrawer()` to open the left drawer and `navigation.getParent('RightDrawer').openDrawer()` to open the right drawer.
145279

146280
## Summary
147281

148-
- To have 2 drawers on the screen, you can use the [`drawerPosition`](drawer-navigator.md#drawerposition) option to position them on `"left"` and `"right"`.
149-
- To open the desired drawer, you can use [`navigation.getParent`](navigation-prop.md#getparent) in combination with the [`id` prop](drawer-navigator.md#id).
282+
- To have multiple drawers, you can use [`react-native-drawer-layout`](drawer-layout.md) directly in combination with a drawer navigator.
283+
- The [`drawerPosition`](drawer-layout.md#drawerposition) prop can be used to position the drawer on the right.
284+
- The methods to control the drawer can be passed down using context API.
285+
- When nesting multiple navigators, you can use [`navigation.getParent`](navigation-prop.md#getparent) in combination with the [`id` prop](drawer-navigator.md#id) to refer to the desired drawer.

versioned_docs/version-7.x/drawer-navigator.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Drawer Navigator renders a navigation drawer on the side of the screen which can
1212
</video>
1313
</div>
1414

15-
This wraps [`react-native-drawer-layout`](drawer-layout.md). If you want to use the tab view without React Navigation integration, use the library directly instead.
15+
This wraps [`react-native-drawer-layout`](drawer-layout.md). If you want to use the drawer without React Navigation integration, use the library directly instead.
1616

1717
## Installation
1818

versioned_docs/version-7.x/multiple-drawers.md

+143-7
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,144 @@ title: Multiple drawers
44
sidebar_label: Multiple drawers
55
---
66

7-
Sometimes we want to have multiple drawers on the same screen: one on the left and one on the right. This can be achieved by [nesting](nesting-navigators.md) 2 [drawer navigators](drawer-navigator.md).
7+
Sometimes we want to have multiple drawers on the same screen: one on the left and one on the right. This can be achieved in 2 ways:
8+
9+
1. By using [`react-native-drawer-layout`](drawer-layout.md) directly (Recommended).
10+
2. By [nesting](nesting-navigators.md) 2 [drawer navigators](drawer-navigator.md).
11+
12+
## Using `react-native-drawer-layout`
13+
14+
When we have multiple drawers, only one of them shows the list of screens. The second drawer may often be used to show some additional information such as the list of users etc.
15+
16+
In such cases, we can use [`react-native-drawer-layout`](drawer-layout.md) directly to render the second drawer. The drawer navigator will be used to render the first drawer and can be nested inside the second drawer:
17+
18+
```js
19+
import * as React from 'react';
20+
import { Button, View } from 'react-native';
21+
import { Drawer } from 'react-native-drawer-layout';
22+
import { createDrawerNavigator } from '@react-navigation/drawer';
23+
24+
function HomeScreen({ navigation }) {
25+
return (
26+
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
27+
<Button onPress={() => navigation.openDrawer()} title="Open drawer" />
28+
</View>
29+
);
30+
}
31+
32+
const LeftDrawer = createDrawerNavigator();
33+
34+
const LeftDrawerScreen = () => {
35+
return (
36+
<LeftDrawer.Navigator screenOptions={{ drawerPosition: 'left' }}>
37+
<LeftDrawer.Screen name="Home" component={HomeScreen} />
38+
</LeftDrawer.Navigator>
39+
);
40+
};
41+
42+
function RightDrawerScreen() {
43+
const [letDrawerOpen, setLeftDrawerOpen] = React.useState(false);
44+
45+
return (
46+
<Drawer
47+
open={rightDrawerOpen}
48+
onOpen={() => setRightDrawerOpen(true)}
49+
onClose={() => setRightDrawerOpen(false)}
50+
drawerPosition="right"
51+
renderDrawerContent={() => <>{/* Right drawer content */}</>}
52+
>
53+
<LeftDrawerScreen />
54+
</Drawer>
55+
);
56+
}
57+
58+
export default function App() {
59+
return (
60+
<NavigationContainer>
61+
<RightDrawerScreen />
62+
</NavigationContainer>
63+
);
64+
}
65+
```
66+
67+
But there is one problem. When we call `navigation.openDrawer()` in our `HomeScreen`, it always opens the left drawer. We don't have access to the right drawer via the `navigation` prop since it's not a navigator.
68+
69+
To solve this, we need to use context API to pass down a function to control the right drawer:
70+
71+
```js
72+
import * as React from 'react';
73+
import { Button, View } from 'react-native';
74+
import { Drawer } from 'react-native-drawer-layout';
75+
import { createDrawerNavigator } from '@react-navigation/drawer';
76+
77+
const RightDrawerContext = React.createContext();
78+
79+
function HomeScreen({ navigation }) {
80+
const { openRightDrawer } = React.useContext(RightDrawerContext);
81+
82+
return (
83+
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
84+
<Button
85+
onPress={() => navigation.openDrawer()}
86+
title="Open left drawer"
87+
/>
88+
<Button onPress={() => openRightDrawer()} title="Open right drawer" />
89+
</View>
90+
);
91+
}
92+
93+
const LeftDrawer = createDrawerNavigator();
94+
95+
const LeftDrawerScreen = () => {
96+
return (
97+
<LeftDrawer.Navigator screenOptions={{ drawerPosition: 'left' }}>
98+
<LeftDrawer.Screen name="Home" component={HomeScreen} />
99+
</LeftDrawer.Navigator>
100+
);
101+
};
102+
103+
function RightDrawerScreen() {
104+
const [letDrawerOpen, setLeftDrawerOpen] = React.useState(false);
105+
106+
const value = React.useMemo(
107+
() => ({
108+
openRightDrawer: () => setRightDrawerOpen(true),
109+
closeRightDrawer: () => setRightDrawerOpen(false),
110+
}),
111+
[]
112+
);
113+
114+
return (
115+
<Drawer
116+
open={rightDrawerOpen}
117+
onOpen={() => setRightDrawerOpen(true)}
118+
onClose={() => setRightDrawerOpen(false)}
119+
drawerPosition="right"
120+
renderDrawerContent={() => <>{/* Right drawer content */}</>}
121+
>
122+
<RightDrawerContext.Provider value={value}>
123+
<LeftDrawerScreen />
124+
</RightDrawerContext.Provider>
125+
</Drawer>
126+
);
127+
}
128+
129+
export default function App() {
130+
return (
131+
<NavigationContainer>
132+
<RightDrawerScreen />
133+
</NavigationContainer>
134+
);
135+
}
136+
```
137+
138+
Here, we are using the `RightDrawerContext` to pass down the `openRightDrawer` function to the `HomeScreen`. Then we use `openRightDrawer` to open the right drawer.
8139

9140
## Nesting 2 drawer navigators
10141

11-
Here we have 2 drawers nested inside each other, one is positioned on left and the other on the right:
142+
An alternative approach is to nest 2 [drawer navigators](drawer-navigator.md) inside each other. This is not recommended since it requires creating an additional screen and more nesting - which can make navigating and type checking more verbose. But this can be useful if both navigators include multiple screens.
143+
144+
Here we have 2 drawer navigators nested inside each other, one is positioned on left and the other on the right:
12145

13146
<samp id="multiple-drawers-issue"/>
14147

@@ -109,7 +242,8 @@ function LeftDrawerScreen() {
109242
return (
110243
<LeftDrawer.Navigator
111244
id="LeftDrawer"
112-
screenOptions={{ drawerPosition: 'left' }}>
245+
screenOptions={{ drawerPosition: 'left' }}
246+
>
113247
<LeftDrawer.Screen name="Home" component={HomeScreen} />
114248
</LeftDrawer.Navigator>
115249
);
@@ -125,7 +259,8 @@ function RightDrawerScreen() {
125259
screenOptions={{
126260
drawerPosition: 'right',
127261
headerShown: false,
128-
}}>
262+
}}
263+
>
129264
<RightDrawer.Screen name="HomeDrawer" component={LeftDrawerScreen} />
130265
</RightDrawer.Navigator>
131266
);
@@ -138,12 +273,13 @@ export default function App() {
138273
</NavigationContainer>
139274
);
140275
}
141-
142276
```
143277

144278
Here, we are passing `"LeftDrawer"` and `"RightDrawer"` strings (you can use any string here) in the `id` prop of the drawer navigators. Then we use `navigation.getParent('LeftDrawer').openDrawer()` to open the left drawer and `navigation.getParent('RightDrawer').openDrawer()` to open the right drawer.
145279

146280
## Summary
147281

148-
- To have 2 drawers on the screen, you can use the [`drawerPosition`](drawer-navigator.md#drawerposition) option to position them on `"left"` and `"right"`.
149-
- To open the desired drawer, you can use [`navigation.getParent`](navigation-prop.md#getparent) in combination with the [`id` prop](drawer-navigator.md#id).
282+
- To have multiple drawers, you can use [`react-native-drawer-layout`](drawer-layout.md) directly in combination with a drawer navigator.
283+
- The [`drawerPosition`](drawer-layout.md#drawerposition) prop can be used to position the drawer on the right.
284+
- The methods to control the drawer can be passed down using context API when using [`react-native-drawer-layout`](drawer-layout.md).
285+
- When nesting multiple navigators, you can use [`navigation.getParent`](navigation-prop.md#getparent) in combination with the [`id` prop](drawer-navigator.md#id) to refer to the desired drawer.

0 commit comments

Comments
 (0)