React Native Navigation example

By , last updated August 25, 2019

There are many navigation options for React Native. In this example we will show how to implement a basic hybrid app navigation with the React Navigation library and native TabNavigator and StackNavigator components.

The result of this tutorial is a simple app with 2 screens: a Welcome screen with a link to the main App Home screen with 3 bars at the bottom:

Step 1. Create a new project.

Run npm install in the command line utility or use the Expo tool and simply click “New Project”.

Step 2. Install extra libraries.

Open the new project in your editor of choice, for example Atom.

You should see a basic set of files with one main javascript file called something like App.js or Main.js.

  1. Syntax error highlighter
    Depending on your editor of choice follow the tutorial How to setup ESLint in Atom or Visual Studio Code in Windows.
  2. React Navigation

    React Navigation is our library of choice and has most of the functionality that we need like tab bars and nav bars. This library is under active development by people working with React Native daily, so we hope the library won’t be abandoned in the near future.

    Run npm install --save react-navigation to add the library to your project dependencies.

Step 3. Create some screens

In our example app we will create 4 simple screens in a folder “screens”: Welcome, Home, Charts and More.

  1. Create a new folder in a project directory and call in “screens”.
  2. Add 4 JavaScript files: WelcomeScreen.js, HomeScreen.js, ChartsScreen.js and MoreScreen.js
  3. Add simple Component code into each of the screens. Here’s what we have in a HomeScreen:
    import React, { Component } from 'react';
    import { View, Text } from 'react-native';
    
    class HomeScreen extends Component {
      render() {
        return (
          <View>
            <Text> HomeScreen </Text>
          </View>
        );
      }
    }
    
    export default HomeScreen;
    
  4. Create a nice looking WelcomeScreen with a “Next” button:
    import React, { Component } from 'react';
    import { View, Dimensions, Button } from 'react-native';
    
    const SCREEN_WIDTH = Dimensions.get('window').width;
    
    class WelcomeScreen extends Component {
      onComplete = () => {
        this.props.navigation.navigate('Home', {},
        {
          type: 'Navigation/NAVIGATE',
          routeName: 'home'
        });
      }
    
      render() {
        return (
            <View style={[styles.slideStyle]} >
              <View>
                <Button
                  title="Next"
                  color='#0288D1'
                  onPress={this.onComplete}
                />
              </View>
            </View>
          );
      }
    }
    
    const styles = {
      slideStyle: {
        flex: 1,
        width: SCREEN_WIDTH,
        flexDirection: 'column',
        justifyContent: 'center',
        backgroundColor: '#03A9F4'
      },
    };
    
    export default WelcomeScreen;
    

Step 4. Create the menu structure

Our goal is to have a Welcome screen show some information. After the first initial step, a user will click a button and go to our main app navigation structure.

The application will have two levels of menus: 1 is to show a welcome screen and 2 are the Home, Charts and More screens.

In order to achieve this, we need to navigators from the react-native library: TabNavigator and StackNavigator. TabNavigator will navigate between the first Welcome screen and further onto the main navigation of the app. StackNavigator will show our main bottom navigation menu with 3 tabs: Home, Charts and More.

Open your App.js (or Main.js) file and do the following steps:

  1. Import TabNavigator and StackNavigator from react-native library:

    import { TabNavigator, StackNavigator } from 'react-navigation';

  2. In the render() method create and show the MainNavigator const variable with all our screens. The App.js file code will look like this:
    import React from 'react';
    import { View, StyleSheet } from 'react-native';
    import { TabNavigator, StackNavigator } from 'react-navigation';
    import HomeScreen from './screens/HomeScreen';
    import ChartsScreen from './screens/ChartsScreen';
    import MoreScreen from './screens/MoreScreen';
    import WelcomeScreen from './screens/WelcomeScreen';
    
    export default class App extends React.Component {
    
      render() {
        const MainNavigator = TabNavigator({
          welcome: { screen: WelcomeScreen },
          main: { screen: TabNavigator({
            Home: { screen: StackNavigator({
              home: { screen: HomeScreen }
            }) },
            Charts: { screen: StackNavigator({
              charts: { screen: ChartsScreen }
            }) },
            More: { screen: StackNavigator({
                more: { screen: MoreScreen }
            }) },
            })
          },
          });
    
        return (
          <View style={styles.container}>
            <MainNavigator />
          </View>
        );
      }
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#fff',
      },
    });
    

    At this point you will see a blue Welcome screen with two bottom tabs and a button “Next” that will redirect you to the Home screen:

    Step 5. Hide invisible bars

    The Welcome screen has it’s own menu with the buttons “Welcome” and “main”, but we don’t really want to see this menu bar. Let’s hide it by adding a tabBarVisible option to the navigation options of the MainNavigator:

    navigationOptions: {
       tabBarVisible: false
    },
    

    Step 6. Other native fixes

    If you are developing for Android, your menu will probably show up at the top of the screen per default. To fix this, you will need to explicitly say to the application that your TabNavigator should have a position at the bottom.

    Include the TabBarBottom component from react-native and include it in the TabNavigator options of the main screen:

    {
       activeTintColor: '#00ffff',
       tabBarPosition: 'bottom',
       tabBarComponent: TabBarBottom,
       swipeEnabled: false,
       lazyLoad: true,
       animationEnabled: false
    }
    

    Here’s what you should see after all the steps:

    The resulting code for App.js will look like this:

    import React from 'react';
    import { View, StyleSheet } from 'react-native';
    import { TabNavigator, StackNavigator, TabBarBottom } from 'react-navigation';
    import HomeScreen from './screens/HomeScreen';
    import ChartsScreen from './screens/ChartsScreen';
    import MoreScreen from './screens/MoreScreen';
    import WelcomeScreen from './screens/WelcomeScreen';
    
    export default class App extends React.Component {
    
      render() {
        const MainNavigator = TabNavigator({
          welcome: { screen: WelcomeScreen },
          main: { screen: TabNavigator({
            Home: { screen: StackNavigator({
              home: { screen: HomeScreen }
            }) },
            Charts: { screen: StackNavigator({
              charts: { screen: ChartsScreen }
            }) },
            More: { screen: StackNavigator({
                more: { screen: MoreScreen }
            }) },
          },
            {
              activeTintColor: '#00ffff',
              tabBarPosition: 'bottom',
              tabBarComponent: TabBarBottom,
              swipeEnabled: false,
              lazyLoad: true,
              animationEnabled: false
            })
          },
        },
        {
          navigationOptions: {
            tabBarVisible: false
          },
        },
      );
    
    
        return (
          <View style={styles.container}>
            <MainNavigator />
          </View>
        );
      }
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#fff',
      },
    });
    

    The project code is also available at GitHub.