Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get previous route name from React Navigation

I am trying to get previous route name to my current screen. Because based on the previous screen name, I have to show/hide few objects in current screen.

To get previous screen name, I have tried following

componentDidMount() {
    const { navigation } = this.props;
    if (navigation.state.params && navigation.state.params.previous_screen) {
       console.log('navigation.state.params.previous_screen', navigation.state.params.previous_screen);
    }
}

But, It's getting undefined in console log.

Any suggestions?

like image 414
Anilkumar iOS - ReactNative Avatar asked May 01 '19 20:05

Anilkumar iOS - ReactNative


5 Answers

For Stack Navigators, I was able to dynamically get the previous route name in react-navigation v6 with:

// `navigation` const is passed to the screen component or from useNavigation()
const routes = navigation.getState()?.routes;
const prevRoute = routes[routes.length - 2]; // -2 because -1 is the current route

Note: This is super useful for dynamically passing params back to a previous screen. Beware of nested routes though, the syntax is slightly different.

if (prevRoute.name === "<Some Routing Key>") {
      navigation.navigate("<Some Routing Key>", params);
}
like image 136
Conor Lamb Avatar answered Nov 06 '22 14:11

Conor Lamb


You need to use NavigationActions

goToScreen = () => {

  const navigateAction = NavigationActions.navigate({
    routeName: 'Profile',

    params: { previous_screen: 'Home' }, // current screen

    action: NavigationActions.navigate({ routeName: 'Profile' }), // screen you want to navigate to
  });

  this.props.navigation.dispatch(navigateAction);
  
};

call the above function in your onPress

<Text onPress={this.goToScreen}>Go to screen</Text>

In your other screen

componentDidMount = () => {
  
  const { navigation } = this.props;
  if (navigation.state.params && navigation.state.params.previous_screen) {

    this.setState({
      previous_screen: navigation.state.params.previous_screen
    });

  } else {
    console.log("ERROR");
  }
};

Working demo

Function version

const goToScreen = () => {
  // assuming that navigation is passed in props
  props.navigation.navigate('Settings', {
    previous_screen: 'Home'
  })
}

And access the params like

const Settings = ({ route }) => {
  const { previous_screen } = route.params;

  return ....
}
like image 37
Junius L. Avatar answered Nov 06 '22 15:11

Junius L.


I got the proper way to found previous route (screen) name from current screen

 props.navigation.dangerouslyGetParent().state.routes 

You will get the list(array) of screen from navigation stack. example like

Output is here

Array(0) [, …]
0:Object {routeName: "ROUNTE_NAME", key: "id-158*****6785-1"}
1:Object {params: Object, routeName: "Screen1", key: "Screen1"}
2:Object {params: Object, routeName: "Screen2", key: "Screen2"}

Thanks guys - K00L ;)

like image 37
kuldip bhalodiya Avatar answered Nov 06 '22 15:11

kuldip bhalodiya


Using react-navigation v5 you can recurse the navigation state using the routes and index to find the current route. Once you have found the current route, an object that doesn't have any child routes, you can subtract 1 from the index to get the previous route.

The code to achieve this looks something like

const getPreviousRouteFromState = (route: NavigationRoute) => {
  let checkRoute = null
  if (route.state && route.state.index > -1 && route.state.routes) {
    checkRoute = route.state.routes[route.state.index]
    if (checkRoute.state && checkRoute.state.routes) {
      return getPreviousRouteFromState(checkRoute)
    }
    const previousRouteIndex = route.state.index - 1
    if (previousRouteIndex > -1) {
      checkRoute = route.state.routes[previousRouteIndex]
    }
  }
  return checkRoute
}

This strategy has some limitations - it will return the current route when navigating back due to limitations of a stack. It also returns the current screen when switching stacks.

like image 1
Corey Avatar answered Nov 06 '22 14:11

Corey


I used the below approach. This may be not the best approach but it does work.

let routes = this.props.navigation.dangerouslyGetState().routes[0].state.history;
for (let idx = routes.length - 1; idx >= 0; idx--) {
  if (routes[idx].type == 'route') {
    let route = routes[idx].key;
    this.props.navigation.navigate(route.substr(0, route.indexOf('-')));
    break;
  }
}
like image 1
Hp Sharma Avatar answered Nov 06 '22 16:11

Hp Sharma