Search code examples
react-nativereact-navigationreact-navigation-stackreact-navigation-drawer

CreateDrawerNavigator inside createStackNavigator


My issue is this: I can't seem to be able to add the hamburguer button on the left (to toggle the drawer) and also I cannot add the title to the drawer depending on the screen (for example, show 'Login' on header when it's on the login screen).

Brief explanation of the code:

The AppNavigation.js handles all the navigation for the app. Including the two drawers (LoggedDrawer and UnloggedDrawer).

They are inside a stack navigator (RootNavigator) and the RootNavigator is inside a container (react-navigation 3.0).

This is the code I have:

AppNavigation.js

const UnloggedDrawer = createDrawerNavigator(
  {
    Home: { screen: HomeScreen },
    Login: { screen: LoginScreen },
    SignUp: { screen: SignUpScreen }
  }, { 
  drawerWidth: SCREEN_WIDTH * 0.6 
  }
)

const LoggedDrawer = createDrawerNavigator(
  {
    Home: { screen: HomeScreen },
    Profile: { screen: ProfileScreen }
  }, {
  contentComponent: (props) => (
    <View style={{ flex: 1 }}>
      <SafeAreaView forceInset={{ top: 'always', horizontal: 'never' }}>
        <DrawerItems {...props} />
        <Button
          color='red'
          title='Logout'
          onPress={() => { props.screenProps.logoutCurrentUser(props) }}
        />
      </SafeAreaView>
    </View>
  ),
  drawerWidth: SCREEN_WIDTH * 0.6,
})

const RootNavigator = createStackNavigator({
  Init: {
    screen: Init,
    navigationOptions: {
      header: null,
    },
  },
  UnloggedDrawer: { screen: UnloggedDrawer },
  LoggedDrawer: { screen: LoggedDrawer }
},
{
  mode: 'modal',
  title: 'Main',
  initialRouteName: 'Init',
  transitionConfig: noTransitionConfig,
})

Init.js

componentWillReceiveProps(props) {
  const { navigation } = props;
  if (props.userReducer.isSignedUp) {
    navigation.dispatch(StackActions.reset(
      { index: 0, key: null, actions: [NavigationActions.navigate({ routeName: 'LoggedDrawer' })] }
    ))
  } else {
    navigation.dispatch(StackActions.reset(
      { index: 0, key: null, actions: [NavigationActions.navigate({ routeName: 'UnloggedDrawer' })] }
    ))
  }
}

On my screens, I have a navigationOptions for all of them just like this (the only difference is the icon), this is only part of the code just as an example:

export default class HomeScreen extends Component {
  static navigationOptions = {
  headerTitle: 'Home',
  drawerIcon: () => (
    <SimpleIcon
      name="home"
      color="rgba(110, 120, 170, 1)"
      size={20}
    />
  )};
}

So what I want to do is:

1. Add a hamburger icon to the header of all screens which will be used to toggle the drawer

2. Add the title on the middle of the header (also for all screens)

What I've tried:

  • Everything I could find on the internet and nothing seems to work.

Also, if my architecture is wrong, please point that out, if also there's a different way to achieve what I'm trying to do it's also accepted.

Thanks in advance. Please help.


Solution

  • So, answering my own question. What I want is easily achieved by using react-native-elements.

    They have a component called 'Header' that you can use on each screen to customize the header.

    I added this to both of drawerNavigators and the stackNavigator.

    headerMode: 'null'
    

    Then for each screen I had to wrap the JSX code in React.Fragment, so it went like this:

    <React.Fragment>
      <Header
        statusBarProps={{ barStyle: 'light-content' }}
        barStyle="light-content"
        leftComponent={
          <SimpleIcon
            name="menu"
            color="#34495e"
            size={20}
          />
        }
        centerComponent={{ text: 'HOME', style: { color: '#34495e' } }}
        containerStyle={{
          backgroundColor: 'white',
          justifyContent: 'space-around',
        }}
      />
    </React.Fragment>
    

    Leaving the answer in case anyone else have the same issue.