How to get current route name in react-navigation?

AndroidIosReact NativeReact Navigation

Android Problem Overview


I want the name of the current route or screen in react-navigation which I want to use inside if condition to make some changes.

Android Solutions


Solution 1 - Android

For react-navigation v5:

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

const route = useRoute();
console.log(route.name);

Solution 2 - Android

You can catch it as the following code:

this.props.navigation.state.routeName

Solution 3 - Android

If you are using nested navigators, you can use this code to get current active screen's state

import { NavigationState } from 'react-navigation';

const getActiveRouteState = function (route: NavigationState): NavigationState {
	if (!route.routes || route.routes.length === 0 || route.index >= route.routes.length) {
		return route;
	}

	const childActiveRoute = route.routes[route.index] as NavigationState;
	return getActiveRouteState(childActiveRoute);
}

Usage:

const activeRoute = getActiveRouteState(this.props.navigation.state);

I'm using this when I need to get current active screen's state from NavigationDrawer.

Solution 4 - Android

This works fine in react-navigation v5.x

this.props.route.name

Solution 5 - Android

While using "react-navigation": "^3.0.8" and DrawerNavigator it can be accessed from the this.props object using this.props.activeItemKey

Solution 6 - Android

const routeNameRef = React.createRef();

<NavigationContainer
  ref={navigationRef}
  onReady={() => routeNameRef.current = navigationRef.current.getCurrentRoute().name}
  onStateChange={() => {
    const previousRouteName = routeNameRef.current
    const currentRouteName = navigationRef.current.getCurrentRoute().name

    if (previousRouteName !== currentRouteName) {
      // Do something here with it
    }

    // Save the current route name for later comparision
    routeNameRef.current = currentRouteName
  }}
  >
  {/* ... */}
</NavigationContainer>
  );

export function getCurrentRouteName(action) {
  return routeNameRef;
}

You can import the function getCurrentRouteName and use this to get the current route name and its working in any nested navigators in React Navigation 5.

Solution 7 - Android

Preparation

register NavigationService.js,see the doc detail in Navigating without the navigation prop

<App
  ref={navigatorRef => {
        NavigationService.setTopLevelNavigator(navigatorRef);
  }}
/>

recursion function

function getCurrentRoute(nav){
    if(Array.isArray(nav.routes)&&nav.routes.length>0){
        return getCurrentRoute(nav.routes[nav.index])
    }else {
        return nav.routeName
    }
}

get current routeName

getCurrentRoute(NavigationService.getNavigator().state.nav)

Solution 8 - Android

In React Navigation v5, I was able to pull the current route name with the below approach:

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

const routes = useNavigationState(state => state.routes)
const currentRoute = routes[routes.length -1].name
console.log('currentRoute: ',currentRoute)

Solution 9 - Android

With version 5.x the best way currently is getFocusedRouteNameFromRoute

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

export default function Stack(route) {
  // If the focused route is not found, we need to assume it's the initial screen
  // This can happen during if there hasn't been any navigation inside the screen
  // In our case, it's "Feed" as that's the first screen inside the navigator
  const routeName = getFocusedRouteNameFromRoute(route) ?? 'Feed';
  return <> ..... </>
}

Solution 10 - Android

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

const App = () => {
  const navigation = useNavigation();
  const { dangerouslyGetState } = useNavigation();
  const { index, routes } = dangerouslyGetState()
  console.log(routes[index].name);

  return(
    <>
    </>
  )
};

Solution 11 - Android

For react-navigation v5, you could use the useNavigationState hook -

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

const state = useNavigationState(state => state);
const routeName = (state.routeNames[state.index]);
console.log(routeName);

Solution 12 - Android

It is possible to get this from the navigationRef attached to the navigation container. Where navigationRef is a ref.

export const navigationRef = React.createRef()

<NavigationContainer
   ref={navigationRef} 
   >
  <Navigator />
</NavigationContainer>

Then use: const currentRouteName = navigationRef.current.getCurrentRoute().name

Alternatively in a functional component you can useRef const navigationRef = React.useRef()

Solution 13 - Android

You can use this in hooks as well.

console.log(navigation.dangerouslyGetState());

Solution 14 - Android

this.props.navigation.state.routeName works only in react-navigation 4 but react-navigation 5 doesn't support it.

The current route name can be achieved by using redux:

-Navigator component passes route object as a prop to the child component

-The Child component receives props and could find the route name in route.name

-To get updated route name on the screen change you can use focus event listener on navigation

<====== Parent Component where navigation is implemented ======>

import React from "react";
import { createMaterialTopTabNavigator } from "@react-navigation/material-top- 
tabs";

import ChildScreen from "../screens/Home/childScreen";

const Tab = createMaterialTopTabNavigator();

const ParentNavigations = () => {

return (

<Tab.Navigator
>
  <Tab.Screen name="ChildScreen" component={ChildScreen} />
</Tab.Navigator>
);
};

export default ParentNavigations;

<===== Child component =====>

import React, { useEffect } from "react";
import { View, StyleSheet } from "react-native";
import { useDispatch } from "react-redux";
import ActionTypes from "../../store/actions/ActionsTypes";

const ChildScreen = ({ navigation, route }) => {
  const dispatch = useDispatch();
  useEffect(() => {
    const unsubscribe = navigation.addListener("focus", () => {
      dispatch({ type: ActionTypes.SETROUTE, payload: route.name }); // every time when screen gets focued it will update the route through redux
    });
    return unsubscribe;
  }, [navigation, route]);
  return (
    <View style={styles.container}>
      <Text>Hello</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#0C0B0B",
  },
});

export default ChildScreen;

Solution 15 - Android

If you just want to see if the current screen is focused, you can use navigation.isFocused(). https://reactnavigation.org/docs/navigation-prop/#isfocused

Example:

_backAction() {
	const { navigation } = this.props;
	if (navigation.isFocused()) {
		this.setState({
			isLeavingApp: true,
		});
	}
}

Solution 16 - Android

const Home = ({ navigation, route }) => {
  // you will see screen key, name and params
  console.log("ROUTE", route); 
  // rest of your code
};

Solution 17 - Android

For react native navigation 5.x use :

props.state.routeNames[props.state.index]

Solution 18 - Android

This is step by step procedure of what Justin.Mathew has described in his answer.

Create a new file called RootNavigation.js and put the below content inside.

// RootNavigation.js

import * as React from 'react';

export const navigationRef = React.createRef(); // we will access all navigation props by importing this in any of the component

Now import the navigationRef from the RootNavigation.js file, and assign NavigationContainer ref to this. After this step navigationRef can function as navigation prop globally.

// App.js

import { NavigationContainer } from '@react-navigation/native';
import { navigationRef } from './RootNavigation';

export default function App() {
  
  handleNavigationRef = (ref) => {
    // DON'T DO navigationRef = ref, cause this will give you "navigationRef is 
    // read only" error.
    navigationRef.current = ref; 
  }
  return (
     <NavigationContainer ref={handleNavigationRef}>
        {/* ... */} 
     </NavigationContainer>
  );
}

USAGE

Now you can import navigationRef in any of the file, even nested ones. And can use this to get the currentRoute and screen details.

//SomeNestedComonent.js

import { navigationRef } from "path/to/RootNavigation.js";

const route = navigationRef.current?.getCurrentRoute(); //current route object
const currentScreen = route.name; // current screen name

Solution 19 - Android

In one line with useNavigationState Hook:

const screenName = useNavigationState((state) => state.routes[state.index].name)

Solution 20 - Android

I have multiple TabNavigators nested in a BottomTabNavigator. I get the current route of the TabNavigator with:

    const pathAndParams = props.navigation.router.getPathAndParamsForState(props.navigation.state) || {}
    const activePath = pathAndParams.path

Solution 21 - Android

This worked for me (I did it inside my navigation drawer)!

const getCurrentRoute = nav => {
  if (Array.isArray(nav.routes) && nav.routes.length > 0) {
    return getCurrentRoute(nav.routes[nav.index]);
  } else {
    return nav.routeName;
  }
};

const currentNavigation = getCurrentRoute(this.props.navigation.state);

Solution 22 - Android

If you are using React Navigation v6 you can use this:

import { useRoute } from '@react-navigation/native';
...
const route = useRoute();

console.log('Current Route: ', route.name);

And if you want to get the name of the screen that you are, and you are inside a nested navigator, you can do this:

import { useNavigationState } from '@react-navigation/native';
...
const routes = useNavigationState(state => state.routes);

const currentRouteIndex =
  routes?.length && routes[routes.length - 1].state?.index;
const currentRoute =
  routes[routes.length - 1].state?.routeNames[currentRouteIndex];

console.log('Current Route: ', currentRoute);

Solution 23 - Android

If you are using reach navigation version 6 you can retrieve screen name by

props.route.name

Solution 24 - Android

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

  //...
  const route = useRoute();
  const routeName = getFocusedRouteNameFromRoute(route); // Get Nested Route Name

Solution 25 - Android

this worked for me try this..

const getCurrentRouteName = () => {
    let _index = props.state.index;
    let _routeName = props.state.routeNames;
    return  _routeName[_index]
}

Solution 26 - Android

For 'wix/react-native-navigation' below is my working solution,

import { Navigation } from 'react-native-navigation';

// Create a variable and set the value from navigation events
let navComponent = null
Navigation.events().registerComponentDidAppearListener(event => navComponent = event)

// navComponent will have the following structure
{"componentId": "Component9", "componentName": "HomeScreen", "componentType": "Component", "passProps": {}}

Solution 27 - Android

In my case, I needed to get the bottom nav index as well, this was my method

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

then

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

let place = routes[routes.length - 1];

if (place.name === 'YOUR_BOTTOM_NAV_NAME') {
   if (place.state.index === 0) {
      //you are in the main screen(BOTTOM_NAV : index 0)
   } else {
      //else navigate to index 0 screen
      navigation.navigate('FirstScreen');
   }
} else if (place.name === 'Another_Screen') {
   navigation.navigate('navigate_to_the_place_you_want');
} else {
   //otherwise come to the first screen
   navigation.navigate('FirstScreen');
}

Solution 28 - Android

Try this,

const appNavigation = useNavigation();
const currentRoute = appNavigation.getCurrentRoute();

This worked for me. Navigation, and its state received as props were unreliable(at least for drawer navigator at root). So I went with this one, which seems to be giving the global navigation state.

Had to use the navigation prop being received in drawer for drawer specific functions like closeDrawer or openDrawer.

export function AppDrawer(props) {

   // for closeDrawer, openDrawer etc.
   const { navigation: drawerNavigation } = props;

   // for referencing current route
   const appNavigation = useNavigation();
   const currentRoute = appNavigation.getCurrentRoute();

   // ... rest of the code
}

Reference for both the variable in console -

enter image description here

Solution 29 - Android

Using version: "@react-navigation/native": "^6.0.8" and this.props.navigation, I did it like this:

    let navegState = this.props.navigation.getState();
    if (!!navegState)
        console.log('CURRENT SCREEN', navegState.routes[navegState.index].name);

Just use navegState.routes[navegState.index] if you want the whole object

Solution 30 - Android

This simple code worked for me. Just add this function to your Util.ts/js file and from your component pass the navigation as the object.

export const getCurrentScreenName = (navigation: any) => {
      return navigation.getState().routes[navigation.getState().index].name;
    };

Solution 31 - Android

We have a lot of answer here but it is hard to apply the fix because navigation is NULL.

WHY?

  • Scenario 1: We are using hooks function like: useRoute, useNavigationState,... but the navigation don't be mounted yet. So it is null and get the Error.

  • Scenario 2: We are using navigation object in the current screen like HomeScreen

    const Home = ({ navigation, route }) => {
       console.log("ROUTE", route); 
    // rest of your code
    };
    

but navigation is NULL in Root app with presence of NavigationContainer

SOLUTION Make sure to checking navigation is not NULL by using onReady() method of React navigation.

const navigationRef = useRef();
const [routeName, setRouteName] = useState('');
return (
<NavigationContainer
  ref={navigationRef}
  onReady={() => {
    const currentRoute = navigationRef.current.getCurrentRoute();
    setRouteName(currentRoute.name);
    // Do whatever you want with navigation here!.
  }}>
  ...
</NavigationContainer>);

That's it.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEshant BistView Question on Stackoverflow
Solution 1 - AndroidppuppimView Answer on Stackoverflow
Solution 2 - AndroidHussam KurdView Answer on Stackoverflow
Solution 3 - AndroidgianlucaparadiseView Answer on Stackoverflow
Solution 4 - AndroidSubrat MishraView Answer on Stackoverflow
Solution 5 - AndroidRishabhView Answer on Stackoverflow
Solution 6 - AndroidAnish YadavView Answer on Stackoverflow
Solution 7 - AndroidKun LuoView Answer on Stackoverflow
Solution 8 - AndroidChris LacailleView Answer on Stackoverflow
Solution 9 - AndroidMarkus MadejaView Answer on Stackoverflow
Solution 10 - AndroidWOLF CRECENTView Answer on Stackoverflow
Solution 11 - Androiduser3291025View Answer on Stackoverflow
Solution 12 - AndroidJustin.MathewView Answer on Stackoverflow
Solution 13 - AndroidMohit GoelView Answer on Stackoverflow
Solution 14 - AndroidShoukat AliView Answer on Stackoverflow
Solution 15 - AndroidThe Happy MonkeyView Answer on Stackoverflow
Solution 16 - AndroidRyan DhungelView Answer on Stackoverflow
Solution 17 - AndroidMouad TahirView Answer on Stackoverflow
Solution 18 - AndroiddjsdevView Answer on Stackoverflow
Solution 19 - AndroidgildniyView Answer on Stackoverflow
Solution 20 - AndroidAregView Answer on Stackoverflow
Solution 21 - AndroidKGS SandaruwanView Answer on Stackoverflow
Solution 22 - AndroidMattView Answer on Stackoverflow
Solution 23 - AndroidBerk KanburlarView Answer on Stackoverflow
Solution 24 - AndroidooolalaView Answer on Stackoverflow
Solution 25 - Androidsaroj kumarView Answer on Stackoverflow
Solution 26 - AndroidVandit MehtaView Answer on Stackoverflow
Solution 27 - AndroidhexhadView Answer on Stackoverflow
Solution 28 - AndroidSanchit KumarView Answer on Stackoverflow
Solution 29 - AndroidJxDarkAngelView Answer on Stackoverflow
Solution 30 - AndroidSwaraj ChawatheView Answer on Stackoverflow
Solution 31 - AndroidnahoangView Answer on Stackoverflow