Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sahil290791/25b0a0414d94d198fa8350f754aaafd0 to your computer and use it in GitHub Desktop.
Save sahil290791/25b0a0414d94d198fa8350f754aaafd0 to your computer and use it in GitHub Desktop.
Migration guide from ex-navigation to react-navigation

Migration guide from ex-navigation to react-navigation

I will be updating this guide frequently as I am currently the migrating a project from ex-navigation to react-navigation. Please let me know if there are any mistakes or if it could be done in a better way.

Hope this guide helps everyone who ever is planning to migrate or is currently migrating to react-navigation.

react-navigation: 1.5.2 and react-native: 0.45.1

Hiding header for a stack:

  • ex-navigation:
<StackNavigation
    defaultRouteConfig={{
      navigationBar: {
        // hiding navigation bar for the entire stack
        visible: false,
      },
    }}
    initialRoute="root"
  />
  • react-navigation:
const RootStack = StackNavigator({
  settings: {
    screen: Settings,
    navigationOptions: {
      header: null,
    },
  },
  contacts: {
    screen: Contacts,
  }
}, {
  initialRouteName: 'root',
  // hiding navigation bar in the entire stack
});

Replacement for NavigationProvider, StackNavigation:

  • There is no NavigationProvider in react-navigation.
  • Declaring a stack in ex-navigation:
return (
      <NavigationProvider router={Router}>
        <StackNavigation
          id="root"
          defaultRouteConfig={{
            navigationBar: {
              visible: true,
              height: navBarHeight,
              elevation: 0,
              tintColor: SColor.orange,
              renderTitle: () => <HeaderLogo />,
              renderRight: (route, props) => <ProfilePicture {...props} route={route} />,
            },
          }}
          initialRoute="home"
        />
      </NavigationProvider>
    );
  • Declaring a stack in react-navigation:
const RootStack = StackNavigator({
  root: {
    screen: HomeContainer,
    navigationOptions: {
      headerTitle: () => <HeaderLogo />,
      headerRight: <BlogProfilePicture />,
      headerStyle: {
        backgroundColor: '#ffffff',
        borderBottomColor: '#ffffff',
      },
    },
  },
}, {
  mode: 'modal',
  initialRouteName: 'root',
  headerMode: 'none',
});

export default RootStack;

// or if you want to add some logic around your stack
// you can also export it from a stateless/stateful component

export default class RootContainer extends React.Component {
  render() {
    return <RootStack />;
  }
}

Passing navigation prop from stack to a screen's navigation-bar in a nested stack:

We would normally need to pass navigation prop to a nested stack in-order to close the child stack and return to parent stack:

  • react-navigation
const ProfileStack = StackNavigator({
  profileSettings: {
    screen: ProfileSettings,
  },
  personalSettings: {
    screen: PersonalSettings,
  }
});

const SettingStack = TabNavigator({
  profile: {
    screen: ProfileStack,
    navigationOptions: ({ navigation }) => {
      headerRight: <ExitButton navigation={navigation} />,
    }
  }
});

const RootStack = StackNavigator({
  Home: {
    screen: HomeContainer,
  },
  Settings: {
    screen: SettingsStack,
  }
}, {
  headerMode: 'modal'
});

Passing route params

  • ex-navigation
// passing params `name: foo`
this.props.navigator.push('home', { name: 'foo' });

// accessing name param
this.props.route.params.name;
  • react-navigation
// passing params `name: foo`
this.props.navigation.navigate('home', { name: 'foo' });

// accessing name param
this.props.navigation.state.params.name;

Dynamically passing initialRouteName, initialRouteParams

  • ex-navigation
<StackNavigation
  id="profile"
  defaultRouteConfig={{
    navigationBar: {
      visible: true,
      tintColor: 'red',
      height: navBarHeight,
      renderTitle: () => <HeaderLogo />,
      elevation: 0,
      renderRight: (route, props) => <ProfileSwitcher route={route} {...props} />,
    },
  }}
  initialRoute={'profile'}
/>
  • react-navigation
const HomeContainer = (props) => {
  const { email, flow } = props.navigation.state.params;
  let routeName = 'home';
  if ((flow === 'loggedOut')) {
    routeName = 'login';
  }
  const Stack = StackNavigator({
    home: {
      screen: Home,
    },
    login: {
      screen: Login,
    },
  }, {
    initialRouteName: routeName,
    initialRouteParams: { flow },
  });
  return <Stack />;
};

Customising header

In react-navigation header consists of 3 parts:

  1. headerLeft (allows us to specify custom component)
  2. headerTitle (the centre portion of the navbar)
  3. headerRight (can be used to add a profile switcher or any other button if needed)
  • Adding header logo/title in centre:
// react navigation
const CustomBackButton = (props) => {
  return (
    <TouchableHighlight onPress={props.onPress}>
      <View>
        <Text>Back</Text>
      </View>
    </TouchableHighlight>
  );
}
const Stack = StackNavigator({
  home: {
    screen: Home,
    navigationOptions: ({ navigation }) => ({
      headerTitle: <Header />,
      // this just changes the back button icon and keeps the default back
      // button behaviour
      headerLeft: <CustomBackButton onPress={navigation.goBack} />,
      // you can pass navigation to headerRight also and navigate to a particular
      // screen on clicking it like to a profile page
      headerRight: <ProfileIcon />,
      headerStyle: {
        backgroundColor: '#ffffff', // backgroundColor color of entire header section
        borderBottomColor: '#ffffff', // border bottom color of entire header
        // if you have multiple headers where the top layer might have a logo and second level might
        // have a tab navigator, one would want both the headers to appear as a single header
        // so, elevation 0 hides the shadow effect/elevation in android
        elevation: 0,
      },
    },
  },
  login: {
    screen: Login,
  },
}, {
  initialRouteName: routeName,
  initialRouteParams: { flow },
});
  • hiding back button alone on a particular screen:

In iOS the headerTitle appears in centre but in Android the header moves towards the left if there is no navigation history (as the header layout is aligned towards left). So in some cases we would want the headerLeft to just occupy left portion, just to make the headerTitle centred.

const PlaceholderButton = () => {
  return (
    <View style={{ backgroundColor: '#fff' }} />
  );
};

const Stack = StackNavigator({
  home: {
    screen: Home,
    navigationOptions: {
      headerTitle: <Header />,
      headerLeft: <PlaceholderButton />,
      headerRight: <ProfileIcon />,
   }
  },
});

Nested TabNavigator's example:

https://snack.expo.io/rJZk7ocuM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment