fbpx Skip to content

Aquent | DEV6

React Navigation Introduction

Written by: Shu Zhang

Navigating between screens is one of the important parts of a mobile app. There were several solutions before the launch of React Navigation. Navigator and NavigatorIOS provide Javascript implementation of a navigation stack. Both allow users to navigate in the app by pop, push, and replace states. However, as the name suggests, NavigatorIOS is not compatible with Android.

Link to demo app: https://github.com/DEV6hub/DEV6Blog/tree/master/react-navigation/demo-app

In 2016, EXPO released a new routing and navigation library called ExNavigiation. ExNavigation is built on top of Navigator and it supports several navigation interfaces like Android back button, navigation bars, and tabs. It also provides optimized transition animations that run on the native UI thread.

In the meantime, the React Native team came up with NavigationExperimental and in January 2017, we got: React Navigation. It’s developed in collaboration between Expo, Facebook and React Native community. It is considered in some ways, the spiritual grandchild of ExNavigation.

Common components in React Navigation are StackNavigator, TabNavigator and DrawerNavigator. The scenario of using StackNavigator is, for example, to navigate from Screen A to Screen B, or from Screen A to Screen C, then back to Screen A. It’s similar with using links on a web page. Users will be redirected to another screen when they tap on a component on the screen. TabNavigator is used when you want to setup several tabs on a screen. Tabs give us a horizontal navigation layout while DrawerNavigator is vertical.

It is common to use nested navigation to setup navigation of an app. A common scenario of combining different types of navigators is to use TabNavigator or DrawerNavigator as root navigator. Child screens of root navigator can be a single screen component, StackNavigator or TabNavigator, the grandchildren screens are usually single screen component.

React Navigation also provides an easy solution for integrating with Redux. You just need to define the app’s navigation states in a reducer. Then pass that down as a navigation prop to a top-level navigator. You can check out the official React Navigation documentation for more details and working examples.

Now I will show how to create an app with nested navigators.

First, use ‘create-react-native-app’ command to create an app that runs on EXPO:

$ create-react-native-app demo-app
$ cd demo-app

And then install React Navigation library:

$ npm install --save react-navigation

Now we’re ready to write our app.

App.js

This is the top level container.

import React from 'react';
import { StyleSheet, View } from 'react-native';
import Expo from 'expo';
import { Drawer } from './Drawer';
  
export default class App extends React.Component {
  render() {
    return (
      <View style={[styles.container]}>
        <Drawer/>
      </View>
    );
  }
}
  
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    marginTop: Expo.Constants.statusBarHeight
  },
});

Drawer.js

Implement the drawer navigation using DrawerNavigator, which has 2 child screens: LibaryList and BookList. (Image 3) LibraryList screen is implemented using a StackNavigator, which has a LibraryScreen and a DetailScreen. The first screen we see by default is LibraryScreen (Image 1). When we click on an item on the screen, for example, the book named “Learning React Native: Building Native Mobile Apps with JavaScript”, we can navigate to the detail view (Image 2).

image1,2,3
// Define our stack navigation
const LibraryStack = StackNavigator({
  LibraryScreen: {
    screen: LibraryScreen
  },
  DetailScreen: {
    screen: DetailScreen,
  },
});
  
// Define our main drawer navigation
export const Drawer = DrawerNavigator({
  LibraryList: {
    screen: LibraryStack,
    navigationOptions: {
      drawerLabel: 'Library',
      drawerIcon: ({ tintColor }) => <Ionicons name="md-book" size={32} color={tintColor} />,
    },
  },
  BookList: {
    screen: Tab,
    navigationOptions: {
      drawerLabel: 'Book List',
      drawerIcon: ({ tintColor }) => <Ionicons name="md-list-box" size={32} color={tintColor} />,
    },
  }
}, {
    initialRouteName: 'LibraryList'
});

Tab.js

Here­­­ we are implementing the second child screen: BookList. (Image 4, 5)

Image4,5

This screen has 2 tabs, BookList and AddBook. So instead of using StackNavigator, we are using TabNavigator here.

export const Tab = TabNavigator({
  BookList: {
    screen: BookListScreen,
    navigationOptions: {
      tabBarLabel: 'Book List',
      tabBarIcon: ({ tintColor }) => <Entypo size={24} name="list" color={tintColor} />,
    }
  },
  AddBook: {
    screen: AddBookScreen,
    navigationOptions: {
      tabBarLabel: 'Add Book',
      tabBarIcon: ({ tintColor }) => <Entypo size={24} name="add-to-list" color={tintColor} />,
    },
  }
}, {
    initialRouteName: 'BookList',
    tabBarPosition: "top",
    tabBarOptions: {
      showLabel: false,
      showIcon: true,
    }
});

Link to demo app: https://github.com/DEV6hub/DEV6Blog/tree/master/react-navigation/demo-app

Want to Master React?

Sign up for our React training course

View Course Details