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.
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 <> ..... </>
}
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": {}}
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
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');
}
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
}
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
Make sure to checking navigation is not NULL by using onReady() method of React navigation.