Skip to content

Commit 4ba28dd

Browse files
committed
Document behavior change regarding preloaded routes
1 parent 015b00d commit 4ba28dd

4 files changed

Lines changed: 48 additions & 17 deletions

File tree

versioned_docs/version-8.x/navigation-actions.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,14 +222,17 @@ If you want to preserve the existing screens but only want to modify the state,
222222
import { CommonActions } from '@react-navigation/native';
223223

224224
navigation.dispatch((state) => {
225-
// Remove all the screens after `Profile`
226-
const index = state.routes.findIndex((r) => r.name === 'Profile');
227-
const routes = state.routes.slice(0, index + 1);
225+
// Remove active screens after `Profile`
226+
const activeRoutes = state.routes.slice(0, state.index + 1);
227+
const extraRoutes = state.routes.slice(state.index + 1);
228+
229+
const index = activeRoutes.findIndex((r) => r.name === 'Profile');
230+
const routes = [...activeRoutes.slice(0, index + 1), ...extraRoutes];
228231

229232
return CommonActions.reset({
230233
...state,
231234
routes,
232-
index: routes.length - 1,
235+
index,
233236
});
234237
});
235238
```
@@ -522,8 +525,6 @@ Depending on the navigator, `preload` may work differently:
522525
- In a stack navigator ([stack](stack-navigator.md), [native stack](native-stack-navigator.md)), the screen will be rendered off-screen and animated in when you navigate to it. If [`getId`](screen.md#id) is specified, it'll be used for the navigation to identify the preloaded screen.
523526
- In a tab or drawer navigator ([bottom tabs](bottom-tab-navigator.md), [material top tabs](material-top-tab-navigator.md), [drawer](drawer-navigator.md), etc.), the existing screen will be rendered as if `lazy` was set to `false`. Calling `preload` on a screen that is already rendered will not have any effect.
524527

525-
When a screen is preloaded in a stack navigator, it can't dispatch navigation actions (e.g. `navigate`, `goBack`, etc.) until it becomes active.
526-
527528
### setParams
528529

529530
The `setParams` action allows to merge params for a certain route. It takes the following arguments:

versioned_docs/version-8.x/navigation-object.md

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -914,8 +914,6 @@ Depending on the navigator, `preload` may work slightly differently:
914914
- In a stack navigator ([stack](stack-navigator.md), [native stack](native-stack-navigator.md)), the screen will be rendered off-screen and animated in when you navigate to it. If [`getId`](screen.md#id) is specified, it'll be used for the navigation to identify the preloaded screen.
915915
- In a tab or drawer navigator ([bottom tabs](bottom-tab-navigator.md), [material top tabs](material-top-tab-navigator.md), [drawer](drawer-navigator.md), etc.), the existing screen will be rendered as if `lazy` was set to `false`. Calling `preload` on a screen that is already rendered will not have any effect.
916916

917-
When a screen is preloaded in a stack navigator, it can't dispatch navigation actions (e.g. `navigate`, `goBack`, etc.) until it becomes active.
918-
919917
### `setParams`
920918

921919
The `setParams` method lets us update the params (`route.params`) of the current screen. `setParams` works like React's `setState` - it shallow merges the provided params object with the current params.
@@ -1698,35 +1696,35 @@ navigation.dispatch((state) => {
16981696
return CommonActions.reset({
16991697
...state,
17001698
routes,
1701-
index: routes.length - 1,
1699+
index: state.index + 1,
17021700
});
17031701
});
17041702
```
17051703

1706-
You can use this functionality to build your own helpers that you can utilize in your app. Here is an example which implements inserting a screen just before the last one:
1704+
You can use this functionality to build your own helpers that you can utilize in your app. Here is an example which implements inserting a screen just before the focused one:
17071705

17081706
```js
17091707
import { CommonActions } from '@react-navigation/native';
17101708

1711-
const insertBeforeLast = (routeName, params) => (state) => {
1709+
const insertBeforeFocused = (routeName, params) => (state) => {
17121710
const routes = [
1713-
...state.routes.slice(0, -1),
1711+
...state.routes.slice(0, state.index),
17141712
{ name: routeName, params },
1715-
state.routes[state.routes.length - 1],
1713+
...state.routes.slice(state.index),
17161714
];
17171715

17181716
return CommonActions.reset({
17191717
...state,
17201718
routes,
1721-
index: routes.length - 1,
1719+
index: state.index + 1,
17221720
});
17231721
};
17241722
```
17251723

17261724
Then use it like:
17271725

17281726
```js
1729-
navigation.dispatch(insertBeforeLast('Home'));
1727+
navigation.dispatch(insertBeforeFocused('Home'));
17301728
```
17311729

17321730
### `canGoBack`

versioned_docs/version-8.x/navigation-state.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ There are few properties present in every navigation state object:
2727
- `type` - Type of the navigator that the state belongs to, e.g. `stack`, `tab`, `drawer`.
2828
- `key` - Unique key to identify the navigator.
2929
- `routeNames` - Name of the screens defined in the navigator. This is an unique array containing strings for each screen.
30-
- `routes` - List of route objects (screens) which are rendered in the navigator. It also represents the history in a stack navigator. There should be at least one item present in this array.
30+
- `routes` - List of route objects (screens) which are rendered in the navigator. In a stack or native stack navigator, the entries up to and including `index` also represent the history. There should be at least one item present in this array.
3131
- `index` - Index of the focused route object in the `routes` array.
3232
- `history` - An optional list of visited items. See [History stack](#history-stack) for more details.
3333
- `stale` - A navigation state is assumed to be stale unless the `stale` property is explicitly set to `false`. This means that the state object needs to be ["rehydrated"](#stale-state-objects).

versioned_docs/version-8.x/upgrading-from-7.x.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,39 @@ createBottomTabNavigator({
301301
</TabItem>
302302
</Tabs>
303303

304-
#### Preloaded screens now behave differently
304+
#### Preloaded routes in Stack have been reworked
305+
306+
Preloaded routes in Stack and Native Stack Navigators have been reworked to remove various restrictions.
307+
308+
The rework has 2 main consequences:
309+
310+
##### Stack navigation state shape has changed
311+
312+
Previously, the navigation state for Stack and Native Stack Navigators was as follows:
313+
314+
- `state.routes` - array of route objects for active screens in the stack, limited by `state.index`.
315+
- `state.preloadedRoutes` - array of route objects for preloaded screens in the stack.
316+
317+
After, the rework:
318+
319+
- `state.routes` - array of route objects for all screens, including preloaded screens, which can extend beyond `state.index` and the routes after `state.index` are considered preloaded.
320+
- `state.preloadedRoutes` - no longer exists.
321+
322+
So if your code had assumptions about `state.routes` being limited by `state.index` (e.g. determining focused route by checking if it's the last route in `state.routes` instead of using `state.index`), you may need to update it to check for `state.index` instead.
323+
324+
```diff lang=js
325+
- const focusedRoute = state.routes[state.routes.length - 1];
326+
+ const focusedRoute = state.routes[state.index];
327+
```
328+
329+
Similarly, if you were using `state.preloadedRoutes` to get the preloaded routes, you can now get them by slicing `state.routes`:
330+
331+
```diff lang=js
332+
- const preloadedRoutes = state.preloadedRoutes;
333+
+ const preloadedRoutes = state.routes.slice(state.index + 1);
334+
```
335+
336+
##### Preloaded screens behave closer to regular screens
305337

306338
Previously, when a screen was preloaded in Stack and Native Stack Navigators, there were a few restrictions:
307339

0 commit comments

Comments
 (0)