如何跳过嵌套导航器的初始路线?

时间:2019-08-19 12:41:03

标签: react-native react-navigation

我的导航如下:

Loading: SwitchNavigator {
  Auth: Stacknavigator,
  Main: StackNavigator,
  Onboard: StackNavigator,
}

StackNavigator中的每一个都有初始路由集。在某些情况下,我想从loading导航器转到onboard导航器上的特定路线。如果我仅使用navigator.navigate('DesiredRoute'),它也会挤入板载initialRoute,因此导航堆栈看起来像[InitialRoute, DesiredRoute]而不是[DesiredRoute]。如何摆脱InitialRoute

代码示例:

// Loading.js

if (loadingComplete) {
  if (!user) {
    navigation.navigate('auth')
    return
  }
  if (user && userData) {
    navigation.navigate('Main')
    return
  }  
  if (onboardingCheckpointCleared) {
    // this creates `['InitialRoute', 'DesiredRoute']` instead of `['DesiredRoute']`
    navigation.navigate('DesiredRoute')
    return
  }
  navigation.navigate('Onboard')
}

3 个答案:

答案 0 :(得分:2)

这是预期的行为,如果只希望显示DesiredRoute,则必须在Loading中设置该路线,如下所示,

Loading: SwitchNavigator {
  Auth: Stacknavigator,
  Main: StackNavigator,
  Onboard: StackNavigator,
  DesiredRoute: ScreenName
}

这样的书写不会产生任何冲突,您可以放心地写。

答案 1 :(得分:0)

我假设您是从DesiredRoute堆栈导航器外部导航到Onboard

如果您不在Onboard导航器之外,则执行navigation.navigate('DesiredRoute')将触发两个操作:首先,它将导航到Onboard堆栈导航器(因此还将激活默认子菜单(InitialRoute的屏幕),然后它将按DesiredRoute。如果您只想在堆栈上放置OnboardDesiredRoute,则可以使用导航操作的子操作,如下所示:

navigation.navigate('Onboard', undefined, StackActions.replace('DesiredRoute'));

第三个参数是可以由第一个参数导航器执行的操作(如果第一个参数不是屏幕而是导航器)。在这里它将导航到Onboard导航器,并将InitialRoute放入堆栈中(自动是Onboard的initialRoute)。但是,StackAction.replace('DesiredRoute')将由Onboard导航器执行,并将InitialRoute替换为DesiredRoute

有关导航的信息,请参见官方文档:https://reactnavigation.org/docs/en/navigation-prop.html#navigate-link-to-other-screens

答案 2 :(得分:0)

我最终创建了一个自定义路由器,该路由器在导航到我的嵌套堆栈时会删除初始路由:

const MyStackNav = createStackNavigator({ ...routes })

const defaultGetStateForAction = MyStackNav.router.getStateForAction
const customGetStateForAction = (action, state) => {
  const defaultNavState = defaultGetStateForAction(action, state)

  // If we're pushing onto a stack that only has a defaulted initialRoute
  if (
    !!defaultNavState &&
    !defaultNavState.routeName && 
    defaultNavState.isTransitioning &&
    defaultNavState.index === 1 &&
    action.type === NavigationActions.NAVIGATE
  ) {
    const newState = {
      ...defaultNavState,
      index: 0, // Decrement index
      routes: defaultNavState.routes.slice(1), // Remove initial route
    }
    return newState
  }
  return defaultNavState
}