This commit adds a new optional property on the `route` object called `path`.
This property will be added if the screen was opened from a deep link.
Having this property helps with few things:
- Preserve the URL when the path was unmatched, e.g. 404 routes
- Expose the path to the user so they could handle it manually if needed, e.g. open in a webview
- Avoid changing URL if state to path doesn't match current path, e.g. if orders of params change
Fixes#9102
BREAKING CHANGE: Drawer status is now a union ('open', 'closed') instead of a boolean. This will let us implement more types of status in future.
Following this the following exports have been renamed as well:
- getIsDrawerOpenFromState -> getDrawerStatusFromState
- useIsDrawerOpen -> useDrawerStatus
With this, the user will be able to specify a `getId` function for their screens which returns an unique ID to use for the screen:
```js
<Stack.Screen
name="Profile"
component={ProfileScreen}
getId={({ params }) => params.userId}
/>
```
This is an alternative to the `key` option in `navigate` with several advantages:
- Often users specify a key that's dependent on data already in params, such as `userId`. So it's much easier to specify it one place rather than at every call site.
- Users won't need to deal with generating a unique key for routes manually.
- This will work with other actions such as `push`, and not just navigate.
- With this, it'll be possible to have multiple instances of the screen even if you use `navigate`, which may be desirable in many cases (such as profile screens).
BREAKING CHANGE: Returning to first route after pressing back seems more common in apps. This commit changes the default for tab and drawer navigators to follow this common practice. To preserve previous behavior, you can pass backBehavior=history to tab and drawer navigators.
BREAKING CHANGE: Previous versions of React Navigation merged params on navigation which caused confusion. This commit changes params not to be merged.
The old behaviour can still be achieved by passing `merge: true` explicitly:
```js
CommonActions.navigate({
name: 'bar',
params: { fruit: 'orange' },
merge: true,
})
```
`initialParams` specified for the screen are always merged.
Previously, 'resetRoot' directly performed a 'setState' on the container instead of dispatching an action. This meant that hooks such as listener for 'preventRemove' won't be notified by it. This commit changes it to dispatch a regular 'RESET' action which will behave the same as other actions.
Currently when we receive a deep link after the app is rendered, it always results in a `navigate` action. While it's ok with the default configuration, it may result in incorrect behaviour when a custom `getStateForPath` function is provided and it returns a routes array different than the initial route and new route pair.
The commit changes 2 things:
1. Add ability to reset state via params of `navigate` by specifying a `state` property instead of `screen`
2. Update `getStateForAction` to return an action for reset when necessary according to the deep linking configuration
Closes#8952
The commit improves the navigation state object to have more specific types.
e.g. The `routeNames` array will now have proper type instead of `string[]`
Currently, stack router adds a duplicate route when pushing a new route with a key that already exists. This is a buggy behaviour since keys need to be unique in the stack.
This commit fixes the behaviour to bring the existing route with the same key to focus (and merge new params if any) instead of adding a duplicate route.
If the state being rehydrated contained multiple `routes` and had an `index`, we incorrectly kept the same index even if the index of the focused route changed in the state after rehydration. This commit ensures that we also adjust the index appropriately according to the new index of the focused route.