skip to Main Content

I’ve been struggling to get goBack() working inside a drawer navigator and I’m not even sure my whole approach here is correct. I want a side menu that functions independently from the main screens, as the side menu will only handle global settings, sign-out, etc.

In the example below, at “real” sign-in, initialRouteName will be set to either “Screen A” or “Screen B”. (I could therefore land on either Screen A or Screen B.) If I land on A I’ll have the option to navigate to B and may wish to return to A. If I land on B I’ll never need to go to A. I do not want to see A or B in the side menu as they are nothing to do with the global settings. From B I’ll potentially navigate elsewhere. The side menu should work from Screen A and Screen B.

My problem here is, regardless of whether I land on A or B, or whether I navigate to the side menu (Account or Settings), goBack() always takes me to the first screen in the stack (AccountScreen) and not to the screen I’ve just come from.

Any help is gratefully received:

import React from 'react';
import { Text, View, Button, Alert, TextInput } from 'react-native';
import { NavigationContainer, DrawerActions, getFocusedRouteNameFromRoute } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createDrawerNavigator } from '@react-navigation/drawer';
import {
    DrawerItem,
    DrawerItemList,
    DrawerContentScrollView,
    DrawerToggleButton,
} from '@react-navigation/drawer';

import { SignInScreen } from './ui/signinscreen.js';
import { AccountScreen } from './ui/accountscreen.js';
import { SettingsScreen } from './ui/settingsscreen.js';
import { AScreen } from './ui/ascreen.js';
import { BScreen } from './ui/bscreen.js';

const Drawer = createDrawerNavigator();

const HomeDrawer = () => {
    return (
        <Drawer.Navigator
            screenOptions={{
                headerShown: true,
                headerLeft: false,
                headerRight: () => <DrawerToggleButton />,
            }}
            initialRouteName={"Screen A"}
        >
            <Drawer.Screen name="Account" component={AccountScreen}
                options={({ route, navigation }) => (
                    {
                        headerLeft: () => ( <Button title="< Back" onPress={() => navigation.goBack() } />),
                    }
                )}
            />
            <Drawer.Screen name="Settings" component={SettingsScreen}
                options={({ route, navigation }) => (
                    {
                        headerLeft: () => ( <Button title="< Back" onPress={() => navigation.goBack() } />),
                    }
                )}
            />
            <Drawer.Screen name="Screen A" component={AScreen}
                options={{
                    drawerItemStyle: { height: 0 }
                }}
            />
            <Drawer.Screen name="Screen B" component={BScreen}
                options={({ route, navigation }) => (
                    {
                        headerLeft: () => ( <Button title="< Back" onPress={() => navigation.goBack() } />),
                        drawerItemStyle: { height: 0 }
                    }
                )}
            />
        </Drawer.Navigator>
    );
};

const Stack = createStackNavigator();

const App = () => {
    const [isAuthenticated, setIsAuthenticated] = React.useState(false);

    const handleSignIn = () => {
        // Real sign in mechanism
        setIsAuthenticated(true);
    };

    return (
        <NavigationContainer>{
            <Stack.Navigator initialRouteName="Sign In">
                {isAuthenticated ? (
                    <Stack.Group screenOptions={{ headerShown: false }}>
                        <Stack.Screen name="Home" component={HomeDrawer} />
                    </Stack.Group>

                ) : (
                    <Stack.Group screenOptions={{ headerShown: true }}>
                        <Stack.Screen name="Sign In" options={{ title: "Nav Test" }}>
                            {(props) => (
                                <SignInScreen {...props} onSignIn={handleSignIn} />
                            )}
                        </Stack.Screen>
                    </Stack.Group>
                )}
            </Stack.Navigator>
        }</NavigationContainer>
    );
}

export default App;

2

Answers


  1. Chosen as BEST ANSWER

    It was unbelievable simple in the end so for the benefit of anyone else who finds themselves here, all I had to do was add backBehavior="history" to the HomeDrawer screenOptions.

    I found the reference here - https://reactnavigation.org/docs/bottom-tab-navigator/#backbehavior but it seems to equally apply to drawer navigation.


    • If you using back Button in a header so I have no idea
    • But you can do a custom style and add icon and you can add
      navigation.goback() in this custom button then it’s work for you

    here is simple example it’s working in screen not header
    you can see hope this will help you

    if you use customs header you use like this

    function DetalisScreen

    function DetailsScreen({ navigation }) {
      return (
        <>
          <View
            style={{
              backgroundColor: 'white',
              width: '100%',
              height: 50,
              flexDirection: 'row',
            }}>
            <TouchableOpacity
            onPress={()=>navigation.goBack()}
            >
              <Image
                source={{
                  uri: 'https://cdn-icons-png.flaticon.com/128/507/507257.png',
                }}
                style={{ width: 30, height: 30, marginTop: 7, marginLeft: 3 }}
              />
            </TouchableOpacity>
            <Text
              style={{
                fontSize: 20,
                marginTop: 7,
                marginLeft: 3,
                fontWeight: 'bold',
              }}>
              Home
            </Text>
          </View>
          <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text>Details Screen</Text>
            <Button title="Go to Details" onPress={() => navigation.goBack()} />
          </View>
        </>
      );
    }
    

    App.js

    import * as React from "react";
    import { Button, View, Text } from "react-native";
    import { NavigationContainer } from "@react-navigation/native";
    import { createNativeStackNavigator } from "@react-navigation/native-stack";
    
    function HomeScreen({ navigation }) {
      return (
        <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
          <Text>Home Screen</Text>
          <Button
            title="Go to Details"
            onPress={() => navigation.navigate("Details")}
          />
        </View>
      );
    }
    
    function DetailsScreen({ navigation }) {
      return (
        <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
          <Text>Details Screen</Text>
          <Button title="Go to Details" onPress={() => navigation.goBack()} />
        </View>
      );
    }
    
    const Stack = createNativeStackNavigator();
    
    function App() {
      return (
        <NavigationContainer>
          <Stack.Navigator initialRouteName="Home">
            <Stack.Screen name="Home" component={HomeScreen} />
            <Stack.Screen name="Details" component={DetailsScreen} />
          </Stack.Navigator>
        </NavigationContainer>
      );
    }
    
    export default App;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search