5

I am using this https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html to access my navigation from any source, my file look as follow:

import { createRef } from 'react';

export const navigationRef = createRef();

export function navigate(name, params) {
  return navigationRef.current?.navigate(name, params);
}

export function goBack() {
  return navigationRef.current?.goBack();
}

export function getRootState() {
  return navigationRef.current?.getRootState();
}

This is perfect for my @navigation/drawer, which is outside my stack navigation.

Only one problem the last method is not synchronized and I want to have an active state on my item menu that is the current route.

How is that possible with react navigation 5?

Dimitri Kopriwa
  • 13,139
  • 27
  • 98
  • 204
  • Try this: `navigation.state.routes[navigation.state.index].routeName` ... it depends on the structure of your navigation ... so try to console.log `navigation.state`, and you will get to what you want... – Hend El-Sahli Feb 06 '20 at 13:00
  • Well, I can't. I am not using v4. In v5, I must use `useNavigation()` to access the navigation and because I am outside the stack navigator (I am into the DrawerContent of the drawer navigator and it wrap the stack navigator), then I can't access the `navigation` object this way. This is why I have linked this : https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html – Dimitri Kopriwa Feb 06 '20 at 13:16
  • if you want to access `navigation` object inside a contentComponent of the Drawer: You could try this: `this.props.descriptors.YourStackIdentifer.navigation` ... I mean `navigation` object is there in the props without the need to inject it using `useNavigation` or anything like that... – Hend El-Sahli Feb 06 '20 at 13:31
  • I use ``, in order to use `useNavigation`, you **MUST** be in `` tree, but `DrawerContent` is not so it is not possible to use `useNavigation`. Also, `navigation` is not injected into DrawerContent. – Dimitri Kopriwa Feb 06 '20 at 13:42
  • I'm have same issues with you, i tried with `useNavigation()` and `useNavigationState()` but always have not latest state. Maybe you can try this way, i think currently only this way can achive [State Persistance](https://reactnavigation.org/docs/state-persistence/#!). By using AsyncStorage to get latest state or create a context provider to store the state when change update the context. – Oska Ng Feb 28 '20 at 15:25
  • Please checkout the answer here: https://stackoverflow.com/questions/59005239/how-to-get-current-routename-in-react-navigation-drawer-drawer-compoenent/61329656#61329656 – Sanchitos Apr 21 '20 at 20:02

6 Answers6

6

I am using the following approach to get the current route name in react-navigation v5. https://reactnavigation.org/docs/navigation-prop/#dangerouslygetstate

const {index, routes} = this.props.navigation.dangerouslyGetState();
const currentRoute = routes[index].name;
console.log('current screen', currentRoute);
Sunil Kumar
  • 178
  • 2
  • 7
3

The NavigationContainer has onStateChange prop, useful for this case, check react-navigation docs Screen Tracking for analytics and if you need access without navigation prop see Navigating without the navigation prop

I share the code to get only active routeName

function App(){
    const routeNameRef = React.useRef();
    // Gets the current screen from navigation state
    const getActiveRouteName = (state)=> {
        const route = state.routes[state?.index || 0];

        if (route.state) {
          // Dive into nested navigators
          return getActiveRouteName(route.state);
        }

        return route.name;
    };

    return (<NavigationContainer
    onStateChange={(state) => {
      if (!state) return;
      //@ts-ignore
      routeNameRef.current = getActiveRouteName(state);
    }}
    >
    ...
    </NavigationContainer>)
}
Mike Vargas
  • 186
  • 2
  • 6
2

If you want to know the current screen from a component you can also use this:

export const HomeScreen = ({ navigation, route }) => {

    console.log(route.name);

    return (
        {...}
    );
};
shoopi
  • 121
  • 3
2

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

export const navigationRef = React.createRef()

and

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

Then use: const currentRouteName = navigationRef.current.getCurrentRoute().name to get the current route name.

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

Justin.Mathew
  • 413
  • 5
  • 12
0

There is a util function called getFocusedRouteNameFromRoute(route) which the docs recommends. BUT - it seems its working only for child screen, so I defined the following function to get the active route name:

const getCurrentRouteName = (navigation, route) => {
    if (route.state)
        return getFocusedRouteNameFromRoute(route);
    return route.name;
};
chenop
  • 4,743
  • 4
  • 41
  • 65
-1

This works for me. In navigationRef.js

let navigator;

export const setNavigator = (nav) => {
  navigator = nav;
};

export const getCurrentRoute = () => {
  const route = navigator.getCurrentRoute();
  return route.name;
};

This can be referred from any source like this

import { getCurrentRoute } from '../navigationRef';

const currentScene = getCurrentRoute();
Chandreu
  • 1
  • 1
  • 2