Home > Enterprise >  React-Native goBack() not navigating to previous screen
React-Native goBack() not navigating to previous screen

Time:01-06

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;

CodePudding user response:

  • 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;

CodePudding user response:

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.

  • Related