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

How to go back by backButton in stack navigator that is inside drawer navigator


I have a multiple screens that every which is a stackNavigator. any created stackNavigator is inside drawer. in every screen , when press BackButton of stackNavigator's header, screen navigate to initialRoute always instead back to last screen.

I tested navigation.goBack() and navigation.goBack(null) and navigation.goBack() and navigation.goBack(this.props.navigation.state.key)}

but none of these worked. here is my code:

    const MenuScreenNavigator = createStackNavigator({
    Menu: {
        screen: MenuScreen,
        navigationOptions: ({ navigation }) => ({
            headerLeft: (
                <HeaderBackButton
                    tintColor="white"
                    onPress={() => navigation.goBack()}
                />
            )
    }

i have multiple screen navigator such as Menu navigator: "Load", "Home",... screens. in continue i have drawer navigator:

const drawerConfig = {
    drawerPosition: 'right',
    contentComponent: CustomDrawerContent,
    initialRouteName: "Load"
   }
   const routeConfig = {
    Menu: {
        screen: MenuScreenNavigator,
        navigationOptions: { title: strings.screenName.menu }
    },
    Load: { screen: AuthLoadingScreenNavigator },

    Login: {
        screen: LoginScreenNavigator,
        navigationOptions: {
            drawerLabel: () => null
        }
    },
    User: { screen: UserScreenNavigator }
   }

and then i create drawerNavigator:

   const DrawerNavigator = createDrawerNavigator(routeConfig, drawerConfig)

   export default createAppContainer(DrawerNavigator)

Solution

  • Drawer Navigation

    This navigation method provides a way to directly switch between different screens via a drawer. This slide drawer contains links to different screens of the application.

    Stack Navigation

    This kind of navigator provides a way to transition between screens and manage navigation history. When clicking on a button or a link, a new screen is put on top of the old screen. It is something like push on pop of a stack. User able to go back to the previous screens one by one from the back button.

    So to be able to navigate back you at least have to put a screen over another one, so on your initial pages that you navigated using your drawer you won't be able to go back.

    Example

    Taking the example above you can't go back from screen1 to user, or from screen2 to menu. You have to follow the stack navigator flow. For example:

    • Menu > screen1 > screen4

    then you can go back

    • screen4 > screen1 > Menu

    Now let's jump to a real example taking the above diagram:

    App.js

    import React, { Component } from 'react';
    import { View, Text, TouchableHighlight, Image } from 'react-native';
    import { DrawerNavigator, createStackNavigator } from 'react-navigation';
    
    import Menu from './pages/Menu/Menu';
    import Screen1 from './pages/Menu/Screen1';
    import Screen4 from './pages/Menu/Screen4';
    
    import User from './pages/User/User';
    import Screen2 from './pages/User/Screen2';
    import Screen5 from './pages/User/Screen5';
    
    import Login from './pages/Login/Login';
    import Screen3 from './pages/Login/Screen3';
    import Screen6 from './pages/Login/Screen6';
    
    const MenuStack = createStackNavigator(
      {
        Menu: {
          screen: Menu,
          navigationOptions: {
            header: null,
          },
        },
        Screen1: {
          screen: Screen1,
        },
        Screen4: {
          screen: Screen4,
        },
      },
      {
        initialRouteName: 'Menu',
      }
    );
    
    const UserStack = createStackNavigator(
      {
        User: {
          screen: User,
          navigationOptions: {
            header: null,
          },
        },
        Screen2: {
          screen: Screen2,
        },
        Screen5: {
          screen: Screen5,
        },
      },
      {
        initialRouteName: 'User',
      }
    );
    
    const LoginStack = createStackNavigator(
      {
        Login: {
          screen: Login,
          navigationOptions: {
            header: null,
          },
        },
        Screen3: {
          screen: Screen3,
        },
        Screen6: {
          screen: Screen6,
        },
      },
      {
        initialRouteName: 'Login',
      }
    );
    
    export default DrawerNavigator(
      {
        Menu: {
          screen: MenuStack,
        },
        Info: {
          screen: UserStack,
        },
        Login: {
          screen: LoginStack,
        },
      },
      {
        initialRouteName: 'Menu',
      }
    );
    

    Menu.js, User.js, Login.js

    import React, { Component } from 'react';
    import { View, Text, Button } from 'react-native';
    import Header from '../../Header';
    
    export default class MenuScreen extends Component {
      render() {
        return (
          <View
            style={{
              flex: 1,
              flexDirection: 'column',
            }}>
            <Header {...this.props} />
            <View
              style={{
                flex: 1,
                alignItems: 'center',
                justifyContent: 'center',
              }}>
              <Text style={{ fontWeight: 'bold', fontSize: 22 }}>
                This is Menu Screen
              </Text>
              <Button
                title="Go to Screen1"
                onPress={() => this.props.navigation.navigate('Screen1')}
              />
            </View>
          </View>
        );
      }
    }
    

    Screen1.js, Screen2.js, Screen3.js

    import React, { Component } from 'react';
    import { View, Text, Button } from 'react-native';
    
    export default class Screen2 extends Component {
      render() {
        return (
          <View
            style={{
              flex: 1,
              flexDirection: 'column',
            }}>
            <View
              style={{
                flex: 1,
                alignItems: 'center',
                justifyContent: 'center',
              }}>
              <Text style={{ fontWeight: 'bold', fontSize: 22 }}>
                This is Screen2
              </Text>
              <Button
                title="Go to Screen5"
                onPress={() => this.props.navigation.navigate('Screen5')}
              />
              <Button
                title="Go to Back"
                onPress={() => this.props.navigation.goBack()}
              />
            </View>
          </View>
        );
      }
    }
    

    Screen4.js, Screen5.js, Screen6.js

    import React, { Component } from 'react';
    import { View, Text, Button } from 'react-native';
    
    export default class Screen4 extends Component {
      render() {
        return (
          <View
            style={{
              flex: 1,
              flexDirection: 'column',
            }}>
            <View
              style={{
                flex: 1,
                alignItems: 'center',
                justifyContent: 'center',
              }}>
              <Text style={{ fontWeight: 'bold', fontSize: 22 }}>
                This is Screen4
              </Text>
              <Button
                title="Go to Back"
                onPress={() => this.props.navigation.goBack()}
              />
            </View>
          </View>
        );
      }
    }
    

    Check out the source code: snack.expo.io/@abranhe/react-navigation.