115

I'm using react native navigation (react-navigation) StackNavigator. it starts from the Login page throughout the whole lifecycle of the app. I don't want to have a back option, returning to the Login screen. Does anyone know how it can be hidden on the screen after the login screen? BTW, I'm also hiding it in the login screen by using:

const MainStack = StackNavigator({
  Login: {
    screen: Login,
    navigationOptions: {
      title: "Login",
      header: {
        visible: false,
      },
    },
  },
  // ... other screens here
})
fengd
  • 7,551
  • 3
  • 41
  • 44
EyalS
  • 1,530
  • 2
  • 11
  • 25

30 Answers30

288

1) To make the back button disappear in react-navigation

v5 or newer:

{     
    navigationOptions:  {
    title: 'MyScreen',
    headerLeft: ()=> null,
    // `headerLeft: undefined` should work too
    // `headerLeft: null` should work but could trigger a TS error
}

NOTE: v6 has an extra option: headerBackVisible: false

Whether the back button is visible in the header. You can use it to show a back button alongside headerLeft if you have specified it.

https://reactnavigation.org/docs/native-stack-navigator/#headerbackvisible

v2-v4:

navigationOptions:  {
    title: 'MyScreen',
    headerLeft: null
}

2) If you want to clean navigation stack:

Assuming you are on the screen from which you want to navigate from:

If you are using react-navigation version v5 or newer you can use navigation.reset or CommonActions.reset:

 // Replace current navigation state with a new one,
 // index value will be the current active route:

navigation.reset({
  index: 0,
  routes: [{ name: 'Profile' }],
});

Source and more info here: https://reactnavigation.org/docs/navigation-prop/#reset

Or:

navigation.dispatch(
  CommonActions.reset({
    index: 1,
    routes: [
      { name: 'Home' },
      {
        name: 'Profile',
        params: { user: 'jane' },
      },
    ],
  })
);

Source and more info here: https://reactnavigation.org/docs/navigation-actions/#reset

For older versions of react-navigation:

v2-v4 use StackActions.reset(...)

import { StackActions, NavigationActions } from 'react-navigation';

const resetAction = StackActions.reset({
  index: 0, // <-- currect active route from actions array
  actions: [
    NavigationActions.navigate({ routeName: 'myRouteWithDisabledBackFunctionality' }),
  ],
});

this.props.navigation.dispatch(resetAction);

v1 use NavigationActions.reset

3) For android you will also have to disable the hardware back button using the BackHandler:

http://reactnative.dev/docs/backhandler.html

or if you want to use hooks:

https://github.com/react-native-community/hooks#usebackhandler

otherwise the app will close at android hardware back button press if navigation stack is empty.

Additional sources: thank you to the users that added comments below and helped keeping this answer updated for v5+.

Florin Dobre
  • 9,872
  • 3
  • 59
  • 93
  • 9
    This will remove back button, but in android we can still navigate using device back button. Is there a way to disable that as well? – Gokul Kulkarni Aug 07 '17 at 08:04
  • [This answer](https://stackoverflow.com/a/45953573) expands on how to add params to this navigate action. The [official navigate documentation](https://reactnavigation.org/docs/navigation-prop.html#navigate-link-to-other-screens) is also helpful. – kas Mar 27 '18 at 14:02
  • If you reset the navigation (which you should if you're actually trying to prevent navigating back to the previous screen) I don't believe you need to nullify the header as well, as it happens automatically. – Pwnrar May 09 '18 at 17:22
  • 3
    And when you're in 2018 use "StackAction.reset(...)" instead of "NavigationActions.reset(...)", see https://reactnavigation.org/docs/en/stack-actions.html – Manuel Jun 25 '18 at 15:56
  • 1
    @FlorinDobre `headerLeft: null` is not really right way for v5 due to TS warnings, need to use `headerLeft: () => null` – Vitalii Obideiko Mar 20 '21 at 09:49
  • Note: In `headerLeft: null` with Typescript I was getting an error in the options of the Navigator. So I had to use `undefined` instead. – Fotios Tsakiris Sep 23 '21 at 10:23
  • 1
    V6^ ```headerBackVisible: false,``` – herbie Sep 01 '22 at 10:40
  • `If you want to clean navigation stack` typically conditional rendering based navigation is better than reset actions – ICW Feb 23 '23 at 16:48
58

Have you considered using this.props.navigation.replace( "HomeScreen" ) instead of this.props.navigation.navigate( "HomeScreen" ).

This way you are not adding anything to the stack. so HomeScreen won't wave anything to go back to if back button pressed in Android or screen swiped to the right in IOS.

More informations check the Documentation. And of course you can hide the back button by setting headerLeft: null in navigationOptions

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Tarik Chakur
  • 1,667
  • 13
  • 9
22

We need to set false to the gesturesEnabled along with headerLeft to null. Because we can navigate back by swiping the screen as well.

navigationOptions:  {
   title: 'Title',
   headerLeft: null,
   gestureEnabled: false,
}
Michel Floyd
  • 18,793
  • 4
  • 24
  • 39
20

If your react navigation v6.x

options={{
   title: "Detail Pembayaran",
   headerTitleStyle:{
      fontWeight:'bold',
   },
   headerBackVisible:false
}}

Reference : React document

Subhashis Pandey
  • 1,473
  • 1
  • 13
  • 16
havis .haltec
  • 201
  • 2
  • 2
18

You can hide the back button using left:null, but for android devices it's still able to go back when the user presses the back button. You need to reset the navigation state and hide the button with left:null

Here are the docs for resetting navigation state:
https://reactnavigation.org/docs/navigation-actions#reset

This solution works for react-navigator 1.0.0-beta.7, however left:null no longer works for the latest version.

Eric Goerens
  • 67
  • 11
JXLai
  • 312
  • 4
  • 10
  • 6
    on iOS you can still slide from the edge of the screen to pop back. Resetting the navigation state is definitely needed. – cameronmoreau Aug 30 '17 at 07:15
14

using the BackHandler from react native worked for me. Just include this line in your ComponentWillMount:

BackHandler.addEventListener('hardwareBackPress', function() {return true})

it will disable back button on android device.

OsamaD
  • 453
  • 7
  • 12
8

For react-navigation V6.0

<Stack.Screen
          name={'Dashboard'}
          component={Dashboard}
          options={{
            gestureEnabled: false,
            headerShown: true,
            headerLeft: () => <></>,
          }}>
</Stack.Screen>
Hitesh Surani
  • 12,733
  • 6
  • 54
  • 65
4

found it myself ;) adding:

  left: null,

disable the default back button.

const MainStack = StackNavigator({
  Login: {
    screen: Login,
    navigationOptions: {
      title: "Login",
      header: {
        visible: false,
      },
    },
  },
  FirstPage: {
    screen: FirstPage,
    navigationOptions: {
      title: "FirstPage",
      header: {
        left: null,
      }
    },
  },
David Schumann
  • 13,380
  • 9
  • 75
  • 96
EyalS
  • 1,530
  • 2
  • 11
  • 25
4

react-navigation versions >= 1.0.0-beta.9

navigationOptions:  {
   headerLeft: null
}
ravibagul91
  • 20,072
  • 5
  • 36
  • 59
Vaibhav KB
  • 1,695
  • 19
  • 17
4

For the latest version React Navigation 5 with Typescript:

<Stack.Screen
    name={Routes.Consultations}
    component={Consultations}
    options={{headerLeft: () => null}}
  />
Yacine
  • 703
  • 2
  • 6
  • 14
4

Since React Navigation v5.7, there's been a new official solution from the docs:

https://reactnavigation.org/docs/preventing-going-back

Use beforeRemove as a navigation listener to prevent back behavior from Android back button, header back button and custom back actions.

mxdi9i7
  • 677
  • 4
  • 13
  • 2
    Yep - this is great for preventing transitions due to unsaved changes. If your goal is to prevent going back to a login or onboarding screen, however, then you can just do `navigation.replace` instead of `navigation.navigate`. – idolize Nov 03 '21 at 20:47
4

I'm using v6, it's works for me:

 <Stack.Screen
    name="ApparelsHome"
    component={ApparelsHome}
    options={{
      headerLeft: () => <></>,
    }}
/>
3

The best option to handle this situation is to use SwitchNavigator provided by React navigation. The purpose of SwitchNavigator is to only ever show one screen at a time. By default, it does not handle back actions and it resets routes to their default state when you switch away. This is the exact behavior that is needed in the authentication flow.

This is a typical way to implement it.

  1. Create 2 stack navigators: One for authentication (sign in, sign up, forgot password, etc) and another for the main APP
  2. Create a screen in which you will check which route from switch navigator you want to show (I usually check this in splash screen by checking if a token is stored in Async storage)

Here is a code implementation of above statements

import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import HomeScreen from "./homeScreenPath" 
import OtherScreen from "./otherScreenPath"
import SignInScreen from "./SignInScreenPath" 
import SplashScreen from "./SplashScreenPath"

const AppStack = createStackNavigator({ Home: HomeScreen, Other: OtherScreen });

const AuthStack = createStackNavigator({ SignIn: SignInScreen });


export default createAppContainer(
  createSwitchNavigator(
    {
      Splash: SplashScreen,
      App: AppStack,
      Auth: AuthStack,
    },
    {
      initialRouteName: 'Splash',
    }
  )
);

Now in SplashScreen you will check the token and navigate accordingly

import React from 'react';
import {
  ActivityIndicator,
  AsyncStorage,
  StatusBar,
  StyleSheet,
  View,
} from 'react-native';

class SplashScreen extends React.Component {
  componentDidMount() {
    this.checkIfLogin();
  }

  // Fetch the token from storage then navigate to our appropriate place
  checkIfLogin = async () => {
    const userToken = await AsyncStorage.getItem('userToken');

    // This will switch to the App screen or Auth screen and this splash
    // screen will be unmounted and thrown away.
    this.props.navigation.navigate(userToken ? 'App' : 'Auth');
  };

  // Render any loading content that you like here
  render() {
    return (
      <View>
        <ActivityIndicator />
        <StatusBar barStyle="default" />
      </View>
    );
  }
}

Once you change routes in SwitchNavigator it removes the older route automatically and hence if you press the back button it will not take you to the auth/login screens anymore

Hadi Mir
  • 4,497
  • 2
  • 29
  • 31
2

We can fix it by setting headerLeft to null

static navigationOptions =({navigation}) => {
    return {
        title: 'Rechercher une ville',
        headerLeft: null,
    }  
}
David Schumann
  • 13,380
  • 9
  • 75
  • 96
2

Simply doing

headerLeft: null

might be deprecated by the time you read this answer. You should use following

   navigationOptions = {
        headerTitle : "Title",
        headerLeft : () => {},
    }
Mohammad Sadiq
  • 5,070
  • 28
  • 29
2

ReactNavigation v 5.0 - Stack option:

options={{
headerLeft: () => { 
 return <></>; 
}
}}
  • Please always describe what you are doing in your answer. It should be updated or removed. Read [How to answer](https://stackoverflow.com/help/how-to-answer) before you provide more answers ^^ – finnmglas Jul 27 '20 at 14:00
2

TO REMOVE BACK HEADER BUTTON

 options={{ headerBackVisible:false,}}

Full Tag

<Stack.Screen name="Name" component={NameScreen} options={{ headerBackVisible:false,}} />
Merrin K
  • 1,602
  • 1
  • 16
  • 27
1

The SwitchNavigator would be the way to accomplish this. SwitchNavigator resets the default routes and unmounts the authentication screen when the navigate action is invoked.

import { createSwitchNavigator, createStackNavigator, createAppContainer } from 'react-navigation';

// Implementation of HomeScreen, OtherScreen, SignInScreen, AuthLoadingScreen
// goes here.

const AppStack = createStackNavigator({ Home: HomeScreen, Other: OtherScreen });
const AuthStack = createStackNavigator({ SignIn: SignInScreen });

export default createAppContainer(createSwitchNavigator(
  {
    AuthLoading: AuthLoadingScreen,
    App: AppStack,
    Auth: AuthStack,
  },
  {
    initialRouteName: 'AuthLoading',
  }
));

After the user goes to the SignInScreen and enters their credentials, you would then call

this.props.navigation.navigate('App');
charliebeckwith
  • 1,449
  • 11
  • 29
1
import React,{useEffect,useState,useRef} from 'react';
import { BackHandler,View } from 'react-native';

export default function App() {

  useEffect(() => {
    const backHandler = BackHandler.addEventListener('hardwareBackPress', () => true)
    return () => backHandler.remove()
  }, [])

return(
<View>

</View>
)}
1

If you are using react native expo CLI then you can simply use

options={{headerBackVisible:false}}

0

In Latest Version (v2) works headerLeft:null. you can add in controller's navigationOptions as bellow

static navigationOptions = {
    headerLeft: null,
};
ravibagul91
  • 20,072
  • 5
  • 36
  • 59
tarikul05
  • 1,843
  • 1
  • 16
  • 24
0

For latest version of React Navigation, even if you use null in some cases it may still show "back" written!

Go for this in your main app.js under your screen name or just go to your class file and add: -

static navigationOptions = {
   headerTitle:'Disable back Options',
   headerTitleStyle: {color:'white'},
   headerStyle: {backgroundColor:'black'},
   headerTintColor: 'red',
   headerForceInset: {vertical: 'never'},
   headerLeft: " "
}
ravibagul91
  • 20,072
  • 5
  • 36
  • 59
Rishav Kumar
  • 4,979
  • 1
  • 17
  • 32
0

i think it is simple just add headerLeft : null , i am using react-native cli, so this is the example :

static navigationOptions = {
    headerLeft : null
};
ravibagul91
  • 20,072
  • 5
  • 36
  • 59
Cevin Ways
  • 984
  • 11
  • 13
0

For react-navigation version 4.x

navigationOptions: () => ({
      title: 'Configuration',
      headerBackTitle: null,
      headerLayoutPreset:'center',
      headerLeft: null
    })
Lovekush Vishwakarma
  • 3,035
  • 23
  • 25
0
headerLeft: null

This won't work in the latest react native version

It should be:

navigationOptions = {
 headerLeft:()=>{},
}

For Typescript:

navigationOptions = {
 headerLeft:()=>{return null},
}
asim mehmood
  • 121
  • 10
0

In react-navigation versions 5.x, you can do it like this:

import { CommonActions } from '@react-navigation/native';

navigation.dispatch(
  CommonActions.reset({
    index: 1,
    routes: [
      { name: 'Home' },
      {
        name: 'Profile',
        params: { user: 'jane' },
      },
    ],
  })
);

You can read more here.

Ankur Kedia
  • 3,453
  • 1
  • 13
  • 15
0

Great Answers Provided Though, but i think this is quite simple

    useEffect(() => {
    props.navigation.addListener("beforeRemove", (e) => {
      e.preventDefault();
    });
  }, [props.navigation]);
olawalejuwonm
  • 1,315
  • 11
  • 17
0

You can also do headerLeft:()=>false to get rid of back button

<Stack.Screen name="ImageScreen" component={ShowImage} options={{title:"SMAART", headerLeft:()=>false}} />
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 04 '21 at 17:18
0

I have working on old project where used React Navigation Version 4
I tried but only things work is ..

passwordEntry: {
      screen: passwordEntry,
      navigationOptions: {
        gestureEnabled: false,
      },
    },
Saurabh Chavan
  • 136
  • 2
  • 5
0

You can use

options={{gestureEnabled: false}}

this you can declare where you are declaring your screen.

      <AuthStack.Screen name="Dashboard" component={DashBoardContainer} options={{gestureEnabled: false}} />

This works for me