how to check if goBack() function is doable in react navigation?

There is a canGoBack() event. I am using React Navigation 5. Though I can't find it in the documentations. to check do console.log(this.props.navigation).

<Button onPress={()=>{
   if(this.props.navigation.canGoBack()){
     this.props.navigation.goBack()
   }else{
     this.doSomething()
   }
}}/>

Note this answer was originally written for react-navigation v3.3.0. You should check the current documentation for react-navigation to make sure that this is still supported and if there are any changes/easier methods.

React-Navigation v3

There is a function in this.props.navigation called dangerouslyGetParent.

It states the following in the documentation:

Another good use case for this is to find the index of the active route in the parent's route list. So in the case of a stack if you are at index 0 then you may not want to render a back button, but if you're somewhere else in the list then you would render a back button.

So we can using the following to get the index of the route

this.props.navigation.dangerouslyGetParent().state.index

So we could use this in the onPress of your Button in the following way to check if we are back at the start of the route.

<Button onPress={() => {
  // get the index of the route
  let index = this.props.navigation.dangerouslyGetParent().state.index;
  // handle the index we get
  if (index > 0) {
    this.props.navigation.goBack();
  } else {
    this.doSomething();
  }
}}/>

Update for React-Navigation v5

From the documentation, we can see that dangerouslyGetParent still exists.

This method returns the navigation prop from the parent navigator that the current navigator is nested in. For example, if you have a stack navigator and a tab navigator nested inside the stack, then you can use dangerouslyGetParent inside a screen of the tab navigator to get the navigation prop passed from the stack navigator.

So it could be possible to use the above method for v3 in v5.


canGoBack() in v5

There is also an undocumented api called canGoBack(). This can be accessed from the navigation props in the following way:

this.props.navigation.canGoBack()

This property returns a boolean value if you are able to go back in the stack. Meaning we can update the code that we did for v3 in the following way.

<Button onPress={() => {
  // check to see if it is possible to go back
  let canGoBack = this.props.navigation.canGoBack();
  // handle what we do it we can/cannot go back
  if (canGoBack) {
    this.props.navigation.goBack();
  } else {
    this.doSomething();
  }
}}/>

However, as this is an undocumented api it is liable to change so it could be risky relying on it.


canGoBack() in v6

It now looks like that canGoBack has been documented you can find the information here

This method returns a boolean indicating whether there's any navigation history available in the current navigator, or in any parent navigators. You can use this to check if you can call navigation.goBack():

if (navigation.canGoBack()) {
  navigation.goBack();
}

Don't use this method for rendering content as this will not trigger a re-render. This is only intended for use inside callbacks, event listeners etc.


This function returns a consistent (correct) value in v5 of React Navigation.

function can_go_back(route, navigation){
   const state = navigation.dangerouslyGetState();
   if(!state || !state.routes){ return(false); }
   const first_route = state.routes[0];
   if(!first_route){ return(false); }
   if(first_route.key === route.key){ return(false); }
   else{ return(true); }
};

or with hooks:

  const { dangerouslyGetState } = useNavigation()
  const route = useRoute()
  const canGoBack = dangerouslyGetState()?.routes[0]?.key !== route.key

You would use it with the headerLeft property, passing it the route, and navigation. Like this (modified example from the docs):

<Stack.Screen
  name="Home"
  component={HomeScreen}
  options={({ route, navigation }) => ({
    title: 'Awesome app',
    headerLeft: function(){
      if(!can_go_back(route, navigation){ return(null); }
      else{ 
         // return your button
      }
    },
  })}
/>

I had trouble with canGoBack. It returns an invalid value when pushing a screen. I was using it to render a back button (or not) and the button would appear on the first screen during the animation pushing the second screen onto the navigator.


On React navigation 5, there is a canGoBack() function which is super helpful in this case.