1
votes

This is a "share your knowledge" post. I need this feature and searched many hours for it so i share my solution. Feel free to post CC.

How to get the current route name from main App in react native ?

EDIT : THIS IS FOR react-navigation V1

( knowing that we cannot use this.props.navigation inside it because it define TabNavigator and StackNavigator itself )

/** the trick is with DeviceEventEmitter **/
import { DeviceEventEmitter } from 'react-native';
const initialRouteName = "FluxObservations";


const MyTabView = TabNavigator(
  {
    FluxObservations: { screen: FluxObservations },
    Projects: { screen: Projects },
    NewObservation: { screen: NewObservation},
    Explorer: { screen: Explorer },
    Profil: { screen: Profil }
  },
  {
    swipeEnabled: false,
    initialRouteName: initialRouteName,
    tabBarPosition: "bottom",
    tabBarOptions: { ... },
    navigationOptions: {
      tabBarOnPress: ({ previousScene, scene, jumpToIndex }) => {
        //On each tab change we inject event
        DeviceEventEmitter.emit('updateCurrentRouteName', { currentRouteName: scene.route.routeName });
        // Keep original behaviour
        jumpToIndex(scene.index)
      }
    }
  }
);

const StackView = StackNavigator(
  {
    global: {
      screen: MyTabView,
      headerMode: "none",
      header: null,
      navigationOptions: {
        header: null
      }
    },     
    Credits: { screen: Credits },
    Floristic: { screen: Floristic },
    TermsOfUse: { screen: TermsOfUse },
    LegalNotice: { screen: LegalNotice },
    Options: { screen: Options },
  },
  {mode: 'modal'}
);

export default class App extends React.PureComponent {
  constructor (props) {
    super(props);
    // emit the event for the first tab opened by default, initialRouteName
    DeviceEventEmitter.emit('updateCurrentRouteName', { currentRouteName: initialRouteName });
  }


  // catching all event for route name change ! 
  listeners = {
    update: DeviceEventEmitter.addListener('updateCurrentRouteName', ({ ...currentRouteName }) => {
      console.log("MAIN ", currentRouteName) // Perform update
    })
  }


  render() {
    return (
      <Provider store={store}>
        <PersistGate
          loading={<ActivityIndicator />}
          persistor={persistor}>
          <View style={styles.fullScreen}>
            <StackView />
          </View>
        </PersistGate>
      </Provider>
    );
  }
}

I need this to show tutorial modal on each TabNavigator Screen each time user click on them (until he click "i get it")

1

1 Answers

3
votes

Use the scene tracking method detailed here, in the official docs

function getActiveRouteName(navigationState) {
  if (!navigationState) {
    return null;
  }
  const route = navigationState.routes[navigationState.index];
  // dive into nested navigators
  if (route.routes) {
    return getActiveRouteName(route);
  }
  return route.routeName;
} 

<StackView
  onNavigationStateChange={(prevState, currentState) => {
    const currentScreen = getActiveRouteName(currentState);
    console.log("currentScreen  : " + currentScreen);  
  }}
/>