Skip to content

Commit

Permalink
Update docs for multiple drawers
Browse files Browse the repository at this point in the history
  • Loading branch information
satya164 committed Dec 11, 2023
1 parent c8bb6ca commit e1af85b
Show file tree
Hide file tree
Showing 4 changed files with 288 additions and 16 deletions.
2 changes: 1 addition & 1 deletion versioned_docs/version-6.x/drawer-navigator.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Drawer Navigator renders a navigation drawer on the side of the screen which can
</video>
</div>

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.
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.

## Installation

Expand Down
150 changes: 143 additions & 7 deletions versioned_docs/version-6.x/multiple-drawers.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,144 @@ title: Multiple drawers
sidebar_label: Multiple drawers
---

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).
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:

1. By using [`react-native-drawer-layout`](drawer-layout.md) directly (Recommended).
2. By [nesting](nesting-navigators.md) 2 [drawer navigators](drawer-navigator.md).

## Using `react-native-drawer-layout`

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.

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:

```js
import * as React from 'react';
import { Button, View } from 'react-native';
import { Drawer } from 'react-native-drawer-layout';
import { createDrawerNavigator } from '@react-navigation/drawer';

function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={() => navigation.openDrawer()} title="Open drawer" />
</View>
);
}

const LeftDrawer = createDrawerNavigator();

const LeftDrawerScreen = () => {
return (
<LeftDrawer.Navigator screenOptions={{ drawerPosition: 'left' }}>
<LeftDrawer.Screen name="Home" component={HomeScreen} />
</LeftDrawer.Navigator>
);
};

function RightDrawerScreen() {
const [letDrawerOpen, setLeftDrawerOpen] = React.useState(false);

return (
<Drawer
open={rightDrawerOpen}
onOpen={() => setRightDrawerOpen(true)}
onClose={() => setRightDrawerOpen(false)}
drawerPosition="right"
renderDrawerContent={() => <>{/* Right drawer content */}</>}
>
<LeftDrawerScreen />
</Drawer>
);
}

export default function App() {
return (
<NavigationContainer>
<RightDrawerScreen />
</NavigationContainer>
);
}
```

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.

To solve this, we need to use context API to pass down a function to control the right drawer:

```js
import * as React from 'react';
import { Button, View } from 'react-native';
import { Drawer } from 'react-native-drawer-layout';
import { createDrawerNavigator } from '@react-navigation/drawer';

const RightDrawerContext = React.createContext();

function HomeScreen({ navigation }) {
const { openRightDrawer } = React.useContext(RightDrawerContext);

return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
onPress={() => navigation.openDrawer()}
title="Open left drawer"
/>
<Button onPress={() => openRightDrawer()} title="Open right drawer" />
</View>
);
}

const LeftDrawer = createDrawerNavigator();

const LeftDrawerScreen = () => {
return (
<LeftDrawer.Navigator screenOptions={{ drawerPosition: 'left' }}>
<LeftDrawer.Screen name="Home" component={HomeScreen} />
</LeftDrawer.Navigator>
);
};

function RightDrawerScreen() {
const [letDrawerOpen, setLeftDrawerOpen] = React.useState(false);

const value = React.useMemo(
() => ({
openRightDrawer: () => setRightDrawerOpen(true),
closeRightDrawer: () => setRightDrawerOpen(false),
}),
[]
);

return (
<Drawer
open={rightDrawerOpen}
onOpen={() => setRightDrawerOpen(true)}
onClose={() => setRightDrawerOpen(false)}
drawerPosition="right"
renderDrawerContent={() => <>{/* Right drawer content */}</>}
>
<RightDrawerContext.Provider value={value}>
<LeftDrawerScreen />
</RightDrawerContext.Provider>
</Drawer>
);
}

export default function App() {
return (
<NavigationContainer>
<RightDrawerScreen />
</NavigationContainer>
);
}
```

Here, we are using the `RightDrawerContext` to pass down the `openRightDrawer` function to the `HomeScreen`. Then we use `openRightDrawer` to open the right drawer.

## Nesting 2 drawer navigators

Here we have 2 drawers nested inside each other, one is positioned on left and the other on the right:
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.

Here we have 2 drawer navigators nested inside each other, one is positioned on left and the other on the right:

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

Expand Down Expand Up @@ -109,7 +242,8 @@ function LeftDrawerScreen() {
return (
<LeftDrawer.Navigator
id="LeftDrawer"
screenOptions={{ drawerPosition: 'left' }}>
screenOptions={{ drawerPosition: 'left' }}
>
<LeftDrawer.Screen name="Home" component={HomeScreen} />
</LeftDrawer.Navigator>
);
Expand All @@ -125,7 +259,8 @@ function RightDrawerScreen() {
screenOptions={{
drawerPosition: 'right',
headerShown: false,
}}>
}}
>
<RightDrawer.Screen name="HomeDrawer" component={LeftDrawerScreen} />
</RightDrawer.Navigator>
);
Expand All @@ -138,12 +273,13 @@ export default function App() {
</NavigationContainer>
);
}

```

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.

## Summary

- To have 2 drawers on the screen, you can use the [`drawerPosition`](drawer-navigator.md#drawerposition) option to position them on `"left"` and `"right"`.
- To open the desired drawer, you can use [`navigation.getParent`](navigation-prop.md#getparent) in combination with the [`id` prop](drawer-navigator.md#id).
- To have multiple drawers, you can use [`react-native-drawer-layout`](drawer-layout.md) directly in combination with a drawer navigator.
- The [`drawerPosition`](drawer-layout.md#drawerposition) prop can be used to position the drawer on the right.
- The methods to control the drawer can be passed down using context API.
- 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.
2 changes: 1 addition & 1 deletion versioned_docs/version-7.x/drawer-navigator.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Drawer Navigator renders a navigation drawer on the side of the screen which can
</video>
</div>

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.
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.

## Installation

Expand Down
150 changes: 143 additions & 7 deletions versioned_docs/version-7.x/multiple-drawers.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,144 @@ title: Multiple drawers
sidebar_label: Multiple drawers
---

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).
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:

1. By using [`react-native-drawer-layout`](drawer-layout.md) directly (Recommended).
2. By [nesting](nesting-navigators.md) 2 [drawer navigators](drawer-navigator.md).

## Using `react-native-drawer-layout`

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.

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:

```js
import * as React from 'react';
import { Button, View } from 'react-native';
import { Drawer } from 'react-native-drawer-layout';
import { createDrawerNavigator } from '@react-navigation/drawer';

function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={() => navigation.openDrawer()} title="Open drawer" />
</View>
);
}

const LeftDrawer = createDrawerNavigator();

const LeftDrawerScreen = () => {
return (
<LeftDrawer.Navigator screenOptions={{ drawerPosition: 'left' }}>
<LeftDrawer.Screen name="Home" component={HomeScreen} />
</LeftDrawer.Navigator>
);
};

function RightDrawerScreen() {
const [letDrawerOpen, setLeftDrawerOpen] = React.useState(false);

return (
<Drawer
open={rightDrawerOpen}
onOpen={() => setRightDrawerOpen(true)}
onClose={() => setRightDrawerOpen(false)}
drawerPosition="right"
renderDrawerContent={() => <>{/* Right drawer content */}</>}
>
<LeftDrawerScreen />
</Drawer>
);
}

export default function App() {
return (
<NavigationContainer>
<RightDrawerScreen />
</NavigationContainer>
);
}
```

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.

To solve this, we need to use context API to pass down a function to control the right drawer:

```js
import * as React from 'react';
import { Button, View } from 'react-native';
import { Drawer } from 'react-native-drawer-layout';
import { createDrawerNavigator } from '@react-navigation/drawer';

const RightDrawerContext = React.createContext();

function HomeScreen({ navigation }) {
const { openRightDrawer } = React.useContext(RightDrawerContext);

return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
onPress={() => navigation.openDrawer()}
title="Open left drawer"
/>
<Button onPress={() => openRightDrawer()} title="Open right drawer" />
</View>
);
}

const LeftDrawer = createDrawerNavigator();

const LeftDrawerScreen = () => {
return (
<LeftDrawer.Navigator screenOptions={{ drawerPosition: 'left' }}>
<LeftDrawer.Screen name="Home" component={HomeScreen} />
</LeftDrawer.Navigator>
);
};

function RightDrawerScreen() {
const [letDrawerOpen, setLeftDrawerOpen] = React.useState(false);

const value = React.useMemo(
() => ({
openRightDrawer: () => setRightDrawerOpen(true),
closeRightDrawer: () => setRightDrawerOpen(false),
}),
[]
);

return (
<Drawer
open={rightDrawerOpen}
onOpen={() => setRightDrawerOpen(true)}
onClose={() => setRightDrawerOpen(false)}
drawerPosition="right"
renderDrawerContent={() => <>{/* Right drawer content */}</>}
>
<RightDrawerContext.Provider value={value}>
<LeftDrawerScreen />
</RightDrawerContext.Provider>
</Drawer>
);
}

export default function App() {
return (
<NavigationContainer>
<RightDrawerScreen />
</NavigationContainer>
);
}
```

Here, we are using the `RightDrawerContext` to pass down the `openRightDrawer` function to the `HomeScreen`. Then we use `openRightDrawer` to open the right drawer.

## Nesting 2 drawer navigators

Here we have 2 drawers nested inside each other, one is positioned on left and the other on the right:
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.

Here we have 2 drawer navigators nested inside each other, one is positioned on left and the other on the right:

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

Expand Down Expand Up @@ -109,7 +242,8 @@ function LeftDrawerScreen() {
return (
<LeftDrawer.Navigator
id="LeftDrawer"
screenOptions={{ drawerPosition: 'left' }}>
screenOptions={{ drawerPosition: 'left' }}
>
<LeftDrawer.Screen name="Home" component={HomeScreen} />
</LeftDrawer.Navigator>
);
Expand All @@ -125,7 +259,8 @@ function RightDrawerScreen() {
screenOptions={{
drawerPosition: 'right',
headerShown: false,
}}>
}}
>
<RightDrawer.Screen name="HomeDrawer" component={LeftDrawerScreen} />
</RightDrawer.Navigator>
);
Expand All @@ -138,12 +273,13 @@ export default function App() {
</NavigationContainer>
);
}

```

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.

## Summary

- To have 2 drawers on the screen, you can use the [`drawerPosition`](drawer-navigator.md#drawerposition) option to position them on `"left"` and `"right"`.
- To open the desired drawer, you can use [`navigation.getParent`](navigation-prop.md#getparent) in combination with the [`id` prop](drawer-navigator.md#id).
- To have multiple drawers, you can use [`react-native-drawer-layout`](drawer-layout.md) directly in combination with a drawer navigator.
- The [`drawerPosition`](drawer-layout.md#drawerposition) prop can be used to position the drawer on the right.
- The methods to control the drawer can be passed down using context API when using [`react-native-drawer-layout`](drawer-layout.md).
- 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 comments on commit e1af85b

Please sign in to comment.