Skip to content

Commit d0f8620

Browse files
fix: wrap native stack with NavigationContent (#10288)
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 <[email protected]>
1 parent e9c6904 commit d0f8620

File tree

1 file changed

+21
-18
lines changed

1 file changed

+21
-18
lines changed

packages/native-stack/src/navigators/createNativeStackNavigator.tsx

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,19 @@ function NativeStackNavigator({
2525
screenOptions,
2626
...rest
2727
}: NativeStackNavigatorProps) {
28-
const { state, descriptors, navigation } = useNavigationBuilder<
29-
StackNavigationState<ParamListBase>,
30-
StackRouterOptions,
31-
StackActionHelpers<ParamListBase>,
32-
NativeStackNavigationOptions,
33-
NativeStackNavigationEventMap
34-
>(StackRouter, {
35-
initialRouteName,
36-
children,
37-
screenListeners,
38-
screenOptions,
39-
});
28+
const { state, descriptors, navigation, NavigationContent } =
29+
useNavigationBuilder<
30+
StackNavigationState<ParamListBase>,
31+
StackRouterOptions,
32+
StackActionHelpers<ParamListBase>,
33+
NativeStackNavigationOptions,
34+
NativeStackNavigationEventMap
35+
>(StackRouter, {
36+
initialRouteName,
37+
children,
38+
screenListeners,
39+
screenOptions,
40+
});
4041

4142
React.useEffect(
4243
() =>
@@ -64,12 +65,14 @@ function NativeStackNavigator({
6465
);
6566

6667
return (
67-
<NativeStackView
68-
{...rest}
69-
state={state}
70-
navigation={navigation}
71-
descriptors={descriptors}
72-
/>
68+
<NavigationContent>
69+
<NativeStackView
70+
{...rest}
71+
state={state}
72+
navigation={navigation}
73+
descriptors={descriptors}
74+
/>
75+
</NavigationContent>
7376
);
7477
}
7578

0 commit comments

Comments
 (0)