Get the previous screen name in react native

Viewed 4746

I am using React Navigation v5 in my react-native project.

My screens are hosted by stack navigator:

const MyFlow = ({route, navigation}) => {

   const MyStack = createStackNavigator();

   // there is a MyMenu which is the header menu
   navigation.setOptions({
       headerRight: () => (
         <MyMenuIcon
           navigation={navigation}
           onPress={() =>
             navigation.navigate(SCREENS.MyMenu)
           }
         />
       ),
     });

  return (
    <MyStack.Navigator
       initialRouteName={...}
       ...>
       <MyStack.Screen .../>
       <MyStack.Screen .../>
       ...
    </MyStack.Navigator>
)
}

As you can see above, there is a common header right menu declared, which opens MyMenu component. When I open MyMenu, I need to get from which screen the menu is opened. That's the previous route name(because current route is "MyMenu" when the menu is opened).

I know I can get current route name by:

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

const route = useRoute();
console.log(route.name); // it gives "MyMenu" when I open MyMenu

But how can I get the previous route name to tell from which route MyMenu is opened?

==== I tried the solution ====

I tried:

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

function usePreviousRouteName() {
  return useNavigationState(state =>
    state.routes[state.index - 1]?.name
      ? state.routes[state.index - 1].name
      : 'None'
  );
}

It returns previous route name MyFlow in MyMenu component. But I need to know which screen is behind MyMenu, in other words, I need to know from which screen MyMenu is opened.

3 Answers

React Navigation doesn't keep track of the last focused screens anywhere, so you won't find any built-in functionality to do that. However, you can keep track of it yourself using the onStateChange prop on NavigationContainer:

function App() {
  const navigationRef = React.useRef(null);
  const previousScreens = React.useRef([]);

  return (
    <NavigationContainer
      ref={navigationRef}
      onStateChange={() =>
        previousScreens.current.push(
          navigationRef.current.getCurrentRoute().name
        )
      }
    >
      {/* whatever */}
    </NavigationContainer>
  );
}

Then you can get the previous screen from this array.

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

function usePreviousRouteName() {
  return useNavigationState(state =>
    state.routes[state.index - 1]?.name
      ? state.routes[state.index - 1].name
      : 'None'
  );
}

source: https://reactnavigation.org/docs/use-navigation-state/

Try this way

const routesLength = useNavigationState(state => state.routes.length);

If (routesLength > 1){
  const prevScreenName = useNavigationState((state) => state.routes[state.index - 1].name)
}
Related