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.
When navigating from ScreenA to ScreenB and then back to ScreenA,
react-navigation unconditionally calls `Keyboard.dismiss()`.
If the user is fast enough and taps on a `TextInput` after coming
back from ScreenB, the keyboard opens, just to be dismissed again.
This would also happen if some logic automatically focuses the
`TextInput` in ScreenA. This behaviour can be seen observed in
https://snack.expo.io/lTDZhVNhV.
The `use-subscription` package has a peer dep on latest React. This is problematic when using npm due to it's peer dependency algorithm which installs multiple versions of React when using an older version of React (Native).
This means that we'll need to use an ancient version of `use-subscription` to support older React versions with npm and make sure to never update it, or test with every version.
It's much lower maintenance to incporporate the same update in render logic that `use-subscription` has and not deal with dependencies. So this commit removes the `use-subscription` dependency.
See https://github.com/react-navigation/react-navigation/issues/9021#issuecomment-721679760 for more context.
For apps with push notifications linking to screens inside the app, currently we need to handle them separately (e.g. [instructions for firebase](https://rnfirebase.io/messaging/notifications#handling-interaction), [instructions for expo notifications](https://docs.expo.io/push-notifications/receiving-notifications/)). But if we add a link in the notification to use for deep linking, we can instead reuse the same deep linking logic instead.
This commit adds the `getInitialURL` and `subscribe` options which internally used `Linking` API to allow more advanced implementations by combining it with other sources such as push notifications.
Example usage with Firebase notifications could look like this:
```js
const linking = {
prefixes: ['myapp://', 'https://myapp.com'],
async getInitialURL() {
// Check if app was opened from a deep link
const url = await Linking.getInitialURL();
if (url != null) {
return url;
}
// Check if there is an initial firebase notification
const message = await messaging().getInitialNotification();
// Get the `url` property from the notification which corresponds to a screen
// This property needs to be set on the notification payload when sending it
return message?.notification.url;
},
subscribe(listener) {
const onReceiveURL = ({ url }: { url: string }) => listener(url);
// Listen to incoming links from deep linking
Linking.addEventListener('url', onReceiveURL);
// Listen to firebase push notifications
const unsubscribeNotification = messaging().onNotificationOpenedApp(
(message) => {
const url = message.notification.url;
if (url) {
// If the notification has a `url` property, use it for linking
listener(url);
}
}
);
return () => {
// Clean up the event listeners
Linking.removeEventListener('url', onReceiveURL);
unsubscribeNotification();
};
},
config,
};
```
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
Changes done here will work properly with https://github.com/software-mansion/react-native-screens/pull/624 merged and released. The documentation of `screensEnabled` and `activeLimit` props should also be added. It also enabled `Screens` in iOS stack-navigator by default.
New things:
- `detachInactiveScreens` - prop for navigators with `react-native-screens` integration that can be set by user. It controls if the `react-native-screens` are used by the navigator.
- `detachPreviousScreen` - option that tells to keep the previous screen active. It can be set by user, defaults to `true` for normal mode and `false` for the last screen for mode = “modal”.
Co-authored-by: Satyajit Sahoo <satyajit.happy@gmail.com>
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[]`
This feature adds the sceneContainerStyle prop to the bottom-tabs navigator, to allow setting styles on the container's view. It's already implemented in the material-top-tabs and drawer navigators, I've simply ported it into the bottom-tabs navigator.
It also fixes this issue:
https://github.com/react-navigation/react-navigation/issues/8076
Co-authored-by: Satyajit Sahoo <satyajit.happy@gmail.com>