Skip to content

Commit 83eb00f

Browse files
committed
Add a section on nesting stack navigators
1 parent 50346cf commit 83eb00f

File tree

1 file changed

+77
-2
lines changed

1 file changed

+77
-2
lines changed

versioned_docs/version-5.x/nesting-navigators.md

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ When nesting navigators, there are some things to keep in mind:
4848

4949
For example, when you press the back button inside a nested stack navigator, it'll go back to the previous screen inside the nested stack even if there's another navigator as the parent.
5050

51+
### Each navigator has it's own options
52+
53+
For example, specifying a `title` option in a screen nested in a child navigator won't affect the title shown in a parent navigator.
54+
55+
If you want to achieve this behavior, see the guide for [screen options with nested navigators](screen-options-resolution.md#setting-parent-screen-options-based-on-child-navigators-state). this could be useful if you are rendering a tab navigator inside a stack navigator and want to show the title of the active screen inside the tab navigator in the header of the stack navigator.
56+
5157
### Navigation actions are handled by current navigator and bubble up if couldn't be handled
5258

5359
For example, if you're calling `navigation.goBack()` in a nested screen, it'll only go back in the parent navigator if you're already on the first screen of the navigator. Other actions such as `navigate` work similarly, i.e. navigation will happen in the nested navigator and if the nested navigator couldn't handle it, then the parent navigator will try to handle it. In the above example, when calling `navigate('Messages')`, inside `Feed` screen, the nested tab navigator will handle it, but if you call `navigate('Settings')`, the parent stack navigator will handle it.
@@ -160,13 +166,81 @@ navigation.navigate('Root', {
160166
});
161167
```
162168

169+
## Nesting multiple stack navigators
170+
171+
It's sometimes useful to nest multiple stack navigators, for example, to have [some screens in a modal stack and some in regular stack](modal.md).
172+
173+
When nesting multiple stacks, React Navigation will automatically hide the header from the child stack navigator in order to avoid showing duplicate headers. However, depending on the scenario, it might be more useful to show the header in the child stack navigator instead and hide the header in the parent stack navigator.
174+
175+
To achieve this, you can hide the header in the screen containing the stack using the `headerShown: false` option.
176+
177+
For example:
178+
179+
```js
180+
function Home() {
181+
return (
182+
<NestedStack.Navigator>
183+
<NestedStack.Screen name="Profile" component={Profile} />
184+
<NestedStack.Screen name="Settings" component={Settings} />
185+
</NestedStack.Navigator>
186+
);
187+
}
188+
189+
function App() {
190+
return (
191+
<NavigationContainer>
192+
<RootStack.Navigator>
193+
<RootStack.Screen
194+
name="Home"
195+
component={Home}
196+
options={{ headerShown: false }}
197+
/>
198+
<RootStack.Screen name="EditPost" component={EditPost} />
199+
</RootStack.Navigator>
200+
</NavigationContainer>
201+
);
202+
}
203+
```
204+
205+
A complete example can be found in the [modal guide](modal.md). However, the principle isn't only specific to modals, but any kind of nesting of stack navigators.
206+
207+
In rare cases, you also might want to show both headers from the child and parent stack navigators. In this case, you can explicitly use `headerShown: true` on the child stack navigator to override the default behavior.
208+
209+
For example:
210+
211+
```js
212+
function Home() {
213+
return (
214+
<NestedStack.Navigator screenOptions={{ headerShown: true }}>
215+
<NestedStack.Screen name="Profile" component={Profile} />
216+
<NestedStack.Screen name="Settings" component={Settings} />
217+
</NestedStack.Navigator>
218+
);
219+
}
220+
221+
function App() {
222+
return (
223+
<NavigationContainer>
224+
<RootStack.Navigator>
225+
<RootStack.Screen name="Home" component={Home} />
226+
<RootStack.Screen name="EditPost" component={EditPost} />
227+
</RootStack.Navigator>
228+
</NavigationContainer>
229+
);
230+
}
231+
```
232+
233+
In these examples, we have used a stack navigator directly nested inside another stack navigator, but the same principle applies when there are other navigators in the middle, for example: stack navigator inside a tab navigator which is inside another stack navigator.
234+
235+
When nesting multiple stack navigators, we recommend nesting at most 2 stack navigators, unless absolutely necessary.
236+
163237
## Best practices when nesting
164238

165239
We recommend to reduce nesting navigators to minimal. Try to achieve the behavior you want with as little nesting as possible. Nesting has many downsides:
166240

167-
- Code becomes difficult to follow when navigating to nested screens
168241
- It results in deeply nested view hierarchy which can cause memory and performance issues in lower end devices
169-
- Nesting same type of navigators (e.g. tabs inside tabs, drawer inside drawer etc.) leads to a confusing UX
242+
- Nesting same type of navigators (e.g. tabs inside tabs, drawer inside drawer etc.) might lead to a confusing UX
243+
- With excessive nesting, code becomes difficult to follow when navigating to nested screens, configuring deep link etc.
170244

171245
Think of nesting navigators as a way to achieve the UI you want rather than a way to organize your code. If you want to create separate group of screens for organization, instead of using separate navigators, consider doing something like this:
172246

@@ -187,6 +261,7 @@ const userScreens = {
187261
};
188262

189263
// Then use them in your components by looping over the object and creating screen configs
264+
// You could extract this logic to a utility function and reuse it to simplify your code
190265
<Stack.Navigator>
191266
{Object.entries({
192267
// Use the screens normally

0 commit comments

Comments
 (0)