Skip to content

Commit

Permalink
fix: wrap native stack with NavigationContent (#10288)
Browse files Browse the repository at this point in the history
This pull request fixes #10287.

## The Story
When we use `Link`, we actually use `useLinkProps` hook under the hood and it uses `navigation` object to`dispatch` events. That `navigation` object is a bit different than what we get when we use `useNavigation` hook.

`useNavigation` gets the navigation object [using `NavigationContext`](https://github.com/react-navigation/react-navigation/blob/b91c9b05ff96727f5fa6ef0bec51b5d7eac06600/packages/core/src/useNavigation.tsx#L16) while `useLinkProps` get its `navigation` object [using `NavigationHelperContext`](https://github.com/react-navigation/react-navigation/blob/b91c9b05ff96727f5fa6ef0bec51b5d7eac06600/packages/native/src/useLinkProps.tsx#L26). To my understanding, `NavigationHelperContext` wraps navigators (StackNavigator, TabNavigator etc.) while `NavigationContext` wraps pages. So both return valid navigation object but the target is different. Let's move on to the problem. 

## The Problem
Looks like every navigator wrapped with `NavigationContent` which is basically `NavigationHelpersContextProvider` as you can [see here](https://github.com/react-navigation/react-navigation/blob/b91c9b05ff96727f5fa6ef0bec51b5d7eac06600/packages/core/src/useNavigationBuilder.tsx#L606). Here's a couple of examples:
* [BottomTabNavigator](https://github.com/react-navigation/react-navigation/blob/b91c9b05ff96727f5fa6ef0bec51b5d7eac06600/packages/bottom-tabs/src/navigators/createBottomTabNavigator.tsx#L101)
* [DrawerNavigator](https://github.com/react-navigation/react-navigation/blob/b91c9b05ff96727f5fa6ef0bec51b5d7eac06600/packages/drawer/src/navigators/createDrawerNavigator.tsx#L99)
* [StackNavigator](https://github.com/react-navigation/react-navigation/blob/b91c9b05ff96727f5fa6ef0bec51b5d7eac06600/packages/stack/src/navigators/createStackNavigator.tsx#L110)

But `NativeStackNavigator` [is not wrapped with that](https://github.com/react-navigation/react-navigation/blob/b91c9b05ff96727f5fa6ef0bec51b5d7eac06600/packages/native-stack/src/navigators/createNativeStackNavigator.tsx#L67). This means, when we use `useLinkProps` we don't get our current native stack's navigation reference, we get the closest other navigator which is the `BottomTabNavigator` in our case. When an action is dispatched, it goes through `onAction` function provided by the `useOnAction` hook. It roughly tries to match the navigation action (i.e is that page defined in the navigator) if can't, starts trying the same thing with its parent navigator and goes like that.  Since it accesses to the `TabNavigator` instead of the current active `NativeStack` in our case, it starts that matching process from the wrong navigator and tries matching the route all the way up and ends up finding a match on the latest created stack which is BrowseStack.

Looks like every navigator wrapped with `NavigationContent` in [this PR](1179d56) on May 10, 2021 but `NativeStackNavigator` landed into the repo on May 19, 2021 in [this PR](a55d6a8). This looks like a small mistake and it should be wrapped with `NavigationContent` too. This PR fixes that.

Co-authored-by: Yusuf YILDIRIM <yusuf@tinythin.gs>
  • Loading branch information
yusufyildirim and yusufyildirim committed Jan 26, 2022
1 parent e9c6904 commit d0f8620
Showing 1 changed file with 21 additions and 18 deletions.
39 changes: 21 additions & 18 deletions packages/native-stack/src/navigators/createNativeStackNavigator.tsx
Expand Up @@ -25,18 +25,19 @@ function NativeStackNavigator({
screenOptions,
...rest
}: NativeStackNavigatorProps) {
const { state, descriptors, navigation } = useNavigationBuilder<
StackNavigationState<ParamListBase>,
StackRouterOptions,
StackActionHelpers<ParamListBase>,
NativeStackNavigationOptions,
NativeStackNavigationEventMap
>(StackRouter, {
initialRouteName,
children,
screenListeners,
screenOptions,
});
const { state, descriptors, navigation, NavigationContent } =
useNavigationBuilder<
StackNavigationState<ParamListBase>,
StackRouterOptions,
StackActionHelpers<ParamListBase>,
NativeStackNavigationOptions,
NativeStackNavigationEventMap
>(StackRouter, {
initialRouteName,
children,
screenListeners,
screenOptions,
});

React.useEffect(
() =>
Expand Down Expand Up @@ -64,12 +65,14 @@ function NativeStackNavigator({
);

return (
<NativeStackView
{...rest}
state={state}
navigation={navigation}
descriptors={descriptors}
/>
<NavigationContent>
<NativeStackView
{...rest}
state={state}
navigation={navigation}
descriptors={descriptors}
/>
</NavigationContent>
);
}

Expand Down

0 comments on commit d0f8620

Please sign in to comment.