Drawer + nested StackNavigator issue

Hello there,
first of all thank you for creating react-navigation, let’s hope it become the standard for the react-native navigation.

I’m trying to migrate to react-navigation an application (that was previously using ex-navigation) and I’m having some issues.

The app navigation follows a common flow: There is an authentication screen, if the user is authenticated he can access the “core” of the app, where there is a DrawerNavigator and where each drawer route is a StackNavigator.

I tried to implement the app this way (feel free to tell my I’m dumb if i’m wrong):

1. The first stack
The first screen is a splash screen, it initializes the app and (almost instantly) redirect the user to an authentication screen or to the main screen.
I handled this with a StackNavigator:

const AppStackNavigator = StackNavigator({
  SplashScreen: { screen: SplashScreen },
  AuthScreen: { screen: AuthScreen }, // User not logged in
  MainDrawerNavigator: { screen: MainDrawerNavigator } // User logged in
}, {
  headerMode: 'screen'
})

In SplashScreen I’ll do some stuff and then redirect the user to AuthScreen or to MainDrawerNavigator by resetting the stack (this is the only way to reset the stack at the moment, am I right?):

this.props.navigation.dispatch({
   type: 'Reset',
   index: 0,
  actions: [{ type: 'Navigate', routeName: 'MainDrawerNavigator' }]
})

2. The drawer navigator
If the user is authenticated he can access MainDrawerNavigator, which contains the “core” of the application, and navigate through all the app using the drawer. Each drawer link is a stack navigator.

const MainDrawerNavigator = DrawerNavigator({
  ApplianceStackNavigator: { screen: ApplianceStackNavigator },
  SettingStackNavigator: { screen SettingStackNavigator }
}, {
  initialRouteName: 'ApplianceStackNavigator',
  headerMode: 'screen'
})

3. The stack navigator sub-routes

const ApplianceStackNavigator = StackNavigator({
  ApplianceListScreen: { screen: ApplianceListScreen },
  NewApplianceScreen: { screen: NewApplianceScreen }
}, {
  initialRouteName: 'ApplianceListScreen',
  headerMode: 'screen'
})

And here is where the issue arises.
When I’m inside one of the drawers sub-routes (Appliance/Setting) the navigation doesn’t work correctly.
For example, if I’m in the the ApplianceListScreen and I want to go to the NewApplianceScreen using this.props.navigation.navigate('NewApplianceScreen') I’m expecting that the route gets pushed, but instead the stack is reset (resetted?) to it.


TLDR: Using a StackNavigator as a DrawerNavigator route doesn’t seems to work correctly: the routes don’t get pushed correctly.


I know that this lib is super-young, and that my issue description might be a bit of a mess, but thank you in advance anyway 🙂
P.S.: I wanted to create a repo to show the problem but I discovered this issue while working on a work-related-project and publishing the repo would mean re-writing all the code because I’m on NDA (still, I can setup a dummy repo in the next days if it is needed).

P.P.S: The entire app entry point is the following:

const ApplianceStackNavigator = StackNavigator({
  ApplianceListScreen: { screen: ApplianceListScreen },
  NewApplianceScreen: { screen: NewApplianceScreen }
}, {
  initialRouteName: 'ApplianceListScreen',
  headerMode: 'screen'
})

const MainDrawerNavigator = DrawerNavigator({
  ApplianceStackNavigator: { screen: ApplianceStackNavigator }
}, {
  initialRouteName: 'ApplianceStackNavigator',
  headerMode: 'screen'
})

const AppStackNavigator = StackNavigator({
  SplashScreen: { screen: SplashScreen },
  AuthScreen: { screen: AuthScreen },
  MainDrawerNavigator: { screen: MainDrawerNavigator }
}, {
  headerMode: 'screen'
})

export default class SlowdiveLoveReact extends Component<void, void, void> {
  render () {
    return (
      <View style={styles.container}>
        <Provider store={store}>
          <AppStackNavigator />
        </Provider>
      </View>
    )
  }
}

1 possible answer(s) on “Drawer + nested StackNavigator issue

  1. Ha!
    I found the workaround, I just hide the header from the top AppStackNavigator:

    const ApplianceStackNavigator = StackNavigator({
      ApplianceListScreen: { screen: ApplianceListScreen },
      NewApplianceScreen: { screen: NewApplianceScreen }
    }, {
      initialRouteName: 'ApplianceListScreen',
      headerMode: 'screen'
    })
    
    const MainDrawerNavigator = DrawerNavigator({
      ApplianceStackNavigator: { screen: ApplianceStackNavigator }
    }, {
      initialRouteName: 'ApplianceStackNavigator',
      headerMode: 'screen'
    })
    
    const AppStackNavigator = StackNavigator({
      SplashScreen: { screen: SplashScreen },
      AuthScreen: { screen: AuthScreen },
      MainDrawerNavigator: { screen: MainDrawerNavigator }
    }, {
      headerMode: 'screen',
      navigationOptions: { header: { visible: false } } // ADDED THIS
    })

    Not sure if this is the “right” solution or just a workaround though… In my opinion, It should be possible nesting two StackNavigator without doubling the Header (just like in ex-navigator)… what do you think?