如何在 React Navigation 中导航不同的嵌套堆栈?

129

目标

使用react navigation,从一个导航器中的屏幕导航到另一个导航器中的屏幕。

更多细节

如果我有以下导航器结构:

  • 父导航器
    • 嵌套导航器1
      • 屏幕A
      • 屏幕B
    • 嵌套导航器2
      • 屏幕C
      • 屏幕D

如何从嵌套导航器2下的屏幕D导航到嵌套导航器1下的屏幕A?现在,如果我尝试从屏幕D导航到屏幕A,会出现错误,提示不知道屏幕A,只知道屏幕C和D。

我知道这个问题已经以各种形式在此网站以及GitHub(https://github.com/react-navigation/react-navigation/issues/983, https://github.com/react-navigation/react-navigation/issues/335#issuecomment-280686611)上被提出过,但对于这么基础的问题,缺乏清晰的答案,并且通过搜索数百个GitHub评论来寻找解决方案并不好。

也许这个问题可以为每个遇到这个常见问题的人提供一个明确的解决方法。


你能否发布你的导航栈代码,以及你是否使用了redux navigation? - Pritish Vaidya
17个回答

139

在 React Navigation 5 中,通过将屏幕作为第二个参数传递,这变得更加容易:

navigation.navigate('Nested Navigator 2', { screen: 'screen D' });

如果您有深度嵌套的屏幕,您还可以包括额外的级别:

navigation.navigate('Nested Navigator 2', {
    screen: 'Nested Navigator 3', params: {
        screen: 'screen E'
    }
});

9
你甚至可以通过参数在更深的导航结构中进行导航,例如:根 -> 设置 -> 声音 -> 媒体:navigation.navigate('Root', { screen: 'Settings', params: { screen: 'Sound', params: { screen: 'Media' }}}); - Mika
7
怎样使用push函数? - Nameer
嵌套参数和特定屏幕名称是关键!谢谢。这不在文档中。 - Georges
9
“嵌套导航器2”是回答中提到的一个术语,它是什么以及如何定义它? - user2185592
3
如果屏幕有唯一的名称,为什么流程不是自动的呢?为什么我们仍然需要包括路由? - Zakthedev
显示剩余3条评论

85

8
'NestedNavigator1' 是指什么? - Alexander Trauzzi
3
请尝试这个:this.props.navigation.navigate('NestedNavigator1', {}, NavigationActions.navigate({ routeName: 'screenB', params: {param1: 'value1'} }))。 - jcane86
1
@ZenVentzi,我已经在下面发布了你的问题的答案。 - Helga Sokolova
15
React Navigation v.5.0 中呢? - hakkikonu
3
什么是NavigationActions?似乎我无法从任何地方导入它。 - Keselme
显示剩余2条评论

19

在React Navigation v5中,您可以在此处找到所有说明:

https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator

路由定义

function Root() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Profile" component={Profile} />
      <Stack.Screen name="Settings" component={Settings} />
    </Stack.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator>
        <Drawer.Screen name="Home" component={Home} />
        <Drawer.Screen name="Root" component={Root} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

说明

navigation.navigate('Root', { screen: 'Settings' });

@afrojuju_ 我的过渡非常流畅。 - Rochadsouza
@Rochadsouza,如果我有一个Drawer.Navigator下的另一个屏幕,称为Data,并且我想从Settings屏幕导航到它,该怎么办? 似乎navigation.navigate('App', { screen: 'Data' });不起作用。 - Keselme
1
你甚至可以使用参数在更深的导航结构中进行导航,例如:Root -> Settings -> Sound -> Media:navigation.navigate('Root', { screen: 'Settings', params: { screen: 'Sound', params: { screen: 'Media' }}}); - Mika
14
如果我想从另一个堆栈返回到另一个堆栈怎么办? 我尝试了使用“from”技术,它确实起作用,但是在返回导航的屏幕上,后退箭头/返回按钮消失了。 - Aldor
@Rochadsouza 如果我在开始时不将其聚焦,根屏幕会消失。 - Alauddin Ahmed
显示剩余5条评论

19

React Navigation v3:

Navigation.navigate现在将一个对象作为参数传递。您可以按以下方式设置堆栈名称,然后导航到该堆栈中的路由...

navigation.navigate(NavigationActions.navigate({
    routeName: 'YOUR_STACK',
    action: NavigationActions.navigate({ routeName: 'YOUR_STACK-subRoute' })
}))

'YOUR_STACK' 是您创建堆栈时所命名的堆栈名称...

  YOUR_STACK: createStackNavigator({ subRoute: ... })

我刚刚从最受欢迎的答案中复制粘贴了评论。 - 如果NestedNavigator1里面还有一个名为NestedNavigator1.1的嵌套导航器,其中包含ScreenA1和ScreenB1,那么该怎么办,如果我们想要导航到NestedNavigator1.1,ScreenB1,是否可能? 我正在使用v.3 - ZenVentzi
感谢,它对我有用。React-navigation-V4。 - Saurabh Chavan

12

在React Navigation v5/v6中

堆栈导航到特定屏幕

navigation.navigate('Home', {
   screen: 'Profile',
   params: {userID: 1}
 }
)

如果我们嵌套更多呢?

考虑以下结构:

NAVIGATOR:
  *StackA
    *ScreenC
    *ScreenD
  *StackB
    *ScreenI
    *StackE
      *ScreenF
      *StackG
        *ScreenJ
        *ScreenH

我们希望从StackA中的ScreenC一路跳转到StackB中的ScreenH。实际上,我们可以将参数链接在一起以访问特定的屏幕。
navigation.navigate('StackB',{
   screen: 'StackE',
   params: {
      screen: 'StackG',
      params: {
         screen: 'ScreenH'
      }
   }
  }
)

更多信息请点击此处


1
使用TypeScript,将类型修改为:Home: { screen: string; params: { userID: string } } | undefined; - Fotios Tsakiris

9
React Navigation v5中,你可以这样做:
navigation.navigate('Root', {
  screen: 'Settings',
  params: {
    screen: 'Sound',
    params: {
      screen: 'Media',
    },
  },
});

在上述情况下,你正在导航到媒体屏幕,该媒体屏幕在嵌套在声音屏幕内的导航器中,该声音屏幕又嵌套在设置屏幕内的导航器中。

5

React Navigation v6


文档

function Home() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Feed" component={Feed} />
      <Tab.Screen name="Messages" component={Messages} />
    </Tab.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Home"
          component={Home}
          options={{ headerShown: false }}
        />
        <Stack.Screen name="Profile" component={Profile} />
        <Stack.Screen name="Settings" component={Settings} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

navigation.navigate('Home', { screen: 'Messages' });

9
在我的主堆栈上,如果我最初的路由是“Feed”,并且我使用了这种技术,那么我将无法再回到“Feed”堆栈。 - Alauddin Ahmed
但是在导航交叉堆栈时,类似滑入和滑出的过渡效果能够实现吗?这是如何可能实现的? - undefined

4

在React Navigation 3中

@ZenVentzi,当Nested Navigator 1拥有Nested Navigator 1.1时,这里是多级嵌套导航器的答案。

  • 父级导航器
    • 嵌套导航器1
      • 嵌套导航器1.1
        • 屏幕A
        • 屏幕B
    • 嵌套导航器2
      • 屏幕C
      • 屏幕D

我们只需要根据需要多次注入NavigationActions.navigate()即可。

  const subNavigateAction = NavigationActions.navigate({
    routeName: 'NestedNavigator1.1',
    action: NavigationActions.navigate({
      routeName: 'ScreenB',
      params: {},
    }),
  });
  const navigateAction = NavigationActions.navigate({
    routeName: 'NestedNavigator1',
    action: subNavigateAction,
  });
  this.props.navigation.dispatch(navigateAction);

更新 对于React Navigation 5,请查看上面 @mahi-man 的回答。 https://dev59.com/K1UL5IYBdhLWcg3wx6dw#60556168


1
NavigationActions 是从哪里来的?我无法从任何地方导入它。 - Keselme

3

如果其他方法都不起作用(就像我的情况一样),只需执行以下操作:

Main/Root/App.js:

<StackNavigator ref={(x) => (global.stackNavigator = x)} />

任何位置:

global.stackNavigator.dispatch(
   NavigationActions.navigate({
       routeName: 'Player',
       params: { },
   }),
);

获取错误:'global.stackNavigator.dispatch' 未定义。 - Chandni
当应用程序加载时,你是否立即调用它?它需要在 <StackNavigator /> 被渲染之后,因此至少需要一个渲染/堆栈帧。 - iuliu.net
我正在调用本地通知操作,以将用户移动到特定屏幕,但应用程序呈现的堆栈导航器仍然出现错误。 - Chandni

3

试试这个:

Parent Navigator
  Nested Navigator 1
    screen A
    screen B
  Nested Navigator 2
    screen A
    screen C
    screen D

然后,没必要从2中的D去1中的A,你可以直接从2中的D去A,您可以在这里检查图像每个选项卡的堆栈导航器

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接