Route-centric navigation for React Native

Screen Tracking / Analytics

You might want to do some screen tracking in your apps. Since the entire navigation state is in redux, screen tracking is as simple as writing a redux middleware. Below is a simple middleware that uses routeName as the screen name for tracking screens.

import SegmentIO from 'react-native-segment-io-analytics';

const navigationStateKey = 'navigation';

// gets the current screen from navigation state
function getCurrentScreen(getStateFn) {
  const navigationState = getStateFn()[navigationStateKey];
  // navigationState can be null when exnav is initializing
  if (!navigationState) return null;

  const { currentNavigatorUID, navigators } = navigationState;
  if (!currentNavigatorUID) return null;

  const { index, routes } = navigators[currentNavigatorUID];
  const { routeName } = routes[index];
  return routeName;
}

const screenTracking = ({ getState }) => next => action => {
  if (!action.type.startsWith('EX_NAVIGATION')) return next(action);
  const currentScreen = getCurrentScreen(getState);
  const result = next(action);
  const nextScreen = getCurrentScreen(getState);
  if (nextScreen !== currentScreen) {
    SegmentIO.screen(nextScreen);
  }
  return result;
}

export default screenTracking;

Android back button handling

React Native includes a global BackHandler module. Rather than using this module
directly, include the AndroidBackButtonBehavior component in routes where you'd
like to control the back button. AndroidBackButtonBehavior accepts
isFocused and onBackButtonPress. If isFocused is true, the onBackButtonPress
will fire when the user presses the back button. You need to make sure that onBackButtonPress
returns a promise that wraps the function you want to be called. Eg.

<AndroidBackButtonBehavior isFocused={someboolean}
   onBackButtonPress={()=>Promise.resolve(fireMeWhenSomeBooleanIsTrue)}>
   ...
</AndroidBackButtonBehavior>

GitHub