Navigating React Native apps using React Navigation
Tags: react
Published: 2019-07-08 20:20:43

---
title: Navigating React Native apps using React Navigation
published: true
tags: react
canonical_url: https://blog.logrocket.com/navigating-react-native-apps-using-react-navigation/
---

![](https://thepracticaldev.s3.amazonaws.com/i/izf4rtu06jh1t3rtnmg8.png)

## Introduction

Mobile apps are made up of multiple screens. When building mobile apps, of primary concern is how we handle a user’s navigation through the app — the presentation of the screens and the transitions between them. React Navigation is a standalone library that allows a developer implement this functionality easily.

## React Navigation vs. React Native Navigation

Of the several navigation libraries out there, React Navigation and React Native Navigation are two of the more well known.

React Navigation is written in JavaScript and does not directly use the native navigation APIs on iOS and Android; rather, it recreates some subset of those APIs. This allows for integration of third-party JS plugins, maximum customization, and easier debugging, with no need to learn Objective-C, Swift, Java, Kotlin, etc.

React Native Navigation differs slightly in that it directly uses native navigation APIs on iOS and Android, which allows for a more native look and feel.

For a more detailed exploration of their differences, check out [this blog post](https://dev.to/bnevilleoneill/react-navigation-vs-react-native-navigation-which-is-right-for-you-4gp8-temp-slug-5400022).

## Installation

Assuming you have [Yarn](https://yarnpkg.com/en/) installed, the first step is to set up a React Native app. The easiest way to get started with React Native is with Expo tools because they allow you to start a project without installing and configuring Xcode or Android Studio. Install Expo by running this:

```jsx
npm install -g expo-cli
```

If you encounter any error on Mac, try running it this way:

```jsx
sudo npm install --unsafe-perm -g expo-cli
```

Then run the following to create a new React Native project:

```jsx
expo init ReactNavigationDemo
```

This will kickstart some downloads and ask you to enter some configuration variables. Select `expo-template-blank` and choose `yarn` for the dependency installation, as shown below:

![Creating A React Native Project](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/06/creating-react-native-project.png?resize=2066%2C404&ssl=1)

![Project's Initial Configuration Values](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/06/initial-configuration-values.png?resize=2066%2C370&ssl=1)

![Choosing The Expo Template For Our Project](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/06/choosing-expo-template.png?resize=2064%2C476&ssl=1)

Next, cd into the project folder and open your code editor:

```jsx
cd ReactNavigationDemo
```

If you are using VS Code, you can open the current folder in the editor using:

```jsx
code .
```

Start up the app with:

```jsx
yarn start
```

The next step is to install the `react-navigation` library in your [React Native](https://facebook.github.io/react-native/docs/getting-started) project:

```jsx
yarn add react-navigation
```

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## Navigation patterns

As we discussed earlier, React Navigation is built with JavaScript and lets you create components and navigation patterns that look and feel like truly native ones.

React Navigation uses what’s called a stack navigator to manage the navigation history and presentation of the appropriate screen based on the route taken by a user inside the app.

Only one screen is presented to a user at a given time. Imagine a stack of paper; navigating to a new screen places it on top of the stack, and navigating back removes it from the stack. The stack navigator also provides the transitions and gestures that feel like those of native iOS and Android.

> Note that an app can have more than one stack navigator.

In this section, we’ll explore various navigation patterns used in mobile apps and how to achieve them using React Navigation library.

### 1. Using stack navigator to navigate between screen components

Let’s begin by first creating a `/components` folder in the root of our project. Then we create two files namely `Homescreen.js` and `Aboutscreen`.

```jsx
// Homescreen.js
import React, { Component } from 'react';
import { Button, View, Text } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';

export default class Homescreen extends Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Home Screen</Text>
          <Button
          title="Go to About"
          onPress={() => this.props.navigation.navigate('About')}
/>
      </View>
    )
  }
}
```

Note the `onPress` prop of the button above — we’ll explain what it does later.

```jsx
// Aboutscreen.js
import React, { Component } from 'react';
import { Button, View, Text } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';

export default class Aboutscreen extends Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>About Screen</Text>
      </View>
    )
  }
}
```

Your project folder should look like what’s shown in the image below:

![Our Project Folder's Contents](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2019/06/project-folder-contents.png?resize=512%2C410&ssl=1)

Let’s also make some changes to `App.js`. We’ll import what we need from `react-navigation` and implement our navigation there.

It is useful to implement our navigation in the root `App.js` file because the component exported from `App.js` is the entry point (or root component) for a React Native app, and every other component is a descendant.

As you will see, we will encapsulate every other component inside the navigation functions.

```jsx
// App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { createStackNavigator, createAppContainer } from "react-navigation";

import HomeScreen from './components/HomeScreen';
import AboutScreen from './components/AboutScreen';


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

const AppNavigator = createStackNavigator({
  Home: {
    screen: HomeScreen
  },
  About: {
    screen: AboutScreen
  }
});

const AppContainer = createAppContainer(AppNavigator);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
```

In the code above, `createStackNavigator` provides a way for our app to transition between screens, where each new screen is placed on top of a stack. It is configured to have the familiar iOS and Android look and feel: new screens slide in from the right on iOS and fade in from the bottom on Android.

We pass in a route configuration object to the `createStackNavigator` function. The `Home` route corresponds to the `HomeScreen`, and the `About` route corresponds to `AboutScreen`.

Note that an optional, more concise way of writing the route configuration is the `{ screen: HomeScreen }` configuration format.

Also, we can optionally add another options object, as specified by the [API](https://reactnavigation.org/docs/en/stack-navigator.html#api-definition). If we wanted to indicate which is the initial route, we can add a separate object:

```jsx
const AppNavigator = createStackNavigator({
  Home: {
    screen: HomeScreen
  },
  About: {
    screen: AboutScreen
  }
},{
        initialRouteName: "Home"
});
```

Note that the `Home` and `About` route name-value pairs are enclosed by an overall route object. The options object isn’t enclosed but is a separate object.

The `createStackNavigator` function passes behind the scenes, a navigate prop to the `HomeScreen` and `AboutScreen` components. The navigate prop allows for navigation to a specified screen component. This is why we are able to use it on a button at `HomeScreen.js`, which, when pressed, leads to the `AboutScreen` page, as shown below.

```jsx
<Button title="Go to About" 
onPress={() => this.props.navigation.navigate('About')}
/>
```

In the `App.js` code, we finally created an app container using `const AppContainer = createAppContainer(AppNavigator);`. This container manages navigation state.

To run the app, you’ll need to download the Expo client app. You can get the [‎iOS](https://itunes.apple.com/us/app/expo-client/id982107779?mt=8) and [Android](https://play.google.com/store/apps/details?id=host.exp.exponent&hl=en) versions. Make sure your command line is pointed to the project folder and run the following command.

```jsx
npm start
```

You should see a QR code displayed on the terminal. Scan the QR code with the Expo app on Android, and for the iOS app, you can scan using the normal iPhone camera, which will prompt you with a command to click to open the Expo app.

![Scanning QR Code To Open The Stack Nav Example](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/06/scanning-qr-code-stack-nav-1.gif?resize=288%2C512&ssl=1)

### 2. Using tab navigation

Most mobile apps have more than one screen. A common style of navigation in such mobile apps is tab-based navigation. Here we will focus on how to implement tab navigation using `createBottomTabNavigator`.

Let’s add another screen in our app by creating a `ContactScreen.js` file under `/components`.

```jsx
import React, { Component } from 'react'

export default class ContactScreen extends Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Contact Screen</Text>
      </View>
    )
  }
}
```

Now let’s add to the imports at the top of our `App.js` file:

```jsx
import ContactScreen from './components/ContactScreen';
```

Recall that it is useful to implement our navigation in the root `App.js` component. Therefore, we will implement our tab navigation by importing `createBottomTabNavigator` in `App.js`. Let’s replace `createStackNavigator`:

```jsx
import { createBottomTabNavigator, createAppContainer } from "react-navigation";
```

Also replace `createStackNavigator` with `createBottomTabNavigator` in the `AppNavigator` object:

```jsx
const AppNavigator = createBottomTabNavigator({
  Home: {
    screen: HomeScreen
  },
  About: {
    screen: AboutScreen
  }
}, {
  initialRouteName: "Home"
});
```

Add the new screen to the `navigator` object:

```jsx
const AppNavigator = createBottomTabNavigator({
  Home: {
    screen: HomeScreen
  },
  About: {
    screen: AboutScreen
  },
  Contact: {
    screen: ContactScreen
  }
}, {
  initialRouteName: "Home"
});
```

If you run the app with `npm start` and open it on your Expo client, you should see the bottom nav implemented.

![Scanning QR Code To Open Bottom Nav Example](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/06/scanning-qr-code-bottom-nav-2.gif?resize=288%2C512&ssl=1)

### 3. Using drawer navigation

To immediately begin implementing drawer navigation, replace `createBottomTabNavigator` in the code with `createDrawerNavigator`.

Let’s start at the import statements:

```jsx
import { createDrawerNavigator, createAppContainer } from "react-navigation";
```

Let’s also update the `AppNavigator` variable:

```jsx
const AppNavigator = createDrawerNavigator({
  Home: {
    screen: HomeScreen
  },
  About: {
    screen: AboutScreen
  },
  Contact: {
    screen: ContactScreen
  }
}, {
    initialRouteName: "Home"
  });
```

If you `npm start`, you should be able to see the changes right away. Swipe from the left to see the drawer navigation.

![Scanning QR Code To Open Drawer Nav Example](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/06/scanning-qr-code-drawer-example.gif?resize=288%2C512&ssl=1)

You can customize your drawer navigation by adding icons beside the route names. In the assets folder of this project, there are currently three icons:

![Icons In The Assets Folder](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/06/icons-in-assets-folder.png?resize=824%2C272&ssl=1)

We can customize by adding `navigationOptions` to the following screen component files:

```jsx
// in HomeScreen.js

import React, { Component } from 'react';
import { Button, View, Text, Image, StyleSheet } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';

export default class HomeScreen extends Component {

  static navigationOptions = {
    drawerLabel: 'Home',
    drawerIcon: ({ tintColor }) => (
      <Image
        source={require('../assets/home-icon.png')}
        style={[styles.icon, { tintColor: tintColor }]}
      />
    ),
  };

  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Home Screen</Text>
        <Button
          title="Go to About"
          onPress={() => this.props.navigation.navigate('About')}
        />
      </View>
    )
  }
}

const styles = StyleSheet.create({
  icon: {
    width: 24,
    height: 24,
  }
});
```
```jsx
// in AboutScreen.js

import React, { Component } from 'react';
import { Button, View, Text, Image, StyleSheet } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';

export default class AboutScreen extends Component {

  static navigationOptions = {
    drawerLabel: 'About',
    drawerIcon: ({ tintColor }) => (
      
    ),
  };
  render() {
    return (
      
        About Screen
      
    )
  }
}

const styles = StyleSheet.create({
  icon: {
    width: 24,
    height: 24,
  }
});
```
```jsx
// in ContactScreen.js

import React, { Component } from 'react';
import { Button, View, Text, Image, StyleSheet } from 'react-native';

export default class ContactScreen extends Component {

  static navigationOptions = {
    drawerLabel: 'Contact',
    drawerIcon: ({ tintColor }) => (
      
    ),
  };

  render() {
    return (
      
        Contact Screen
      
    )
  }
}

const styles = StyleSheet.create({
  icon: {
    width: 24,
    height: 24,
  }
});
```

![Navigation Icons In The Drawer Nav](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/06/navigation-icons-in-drawer-nav.gif?resize=288%2C512&ssl=1)

The `tintColor` prop lets you apply any color based on active or inactive states of navigation tabs and labels. For example, we can change the active state color for our nav drawer labels. Go to the `AppNavigator` variable and add to the options object:

```jsx
const AppNavigator = createDrawerNavigator({
  Home: {
    screen: HomeScreen
  },
  About: {
    screen: AboutScreen
  },
  Contact: {
    screen: ContactScreen
  }
}, {
    initialRouteName: "Home",
      contentOptions: {
        activeTintColor: '#e91e63'
     }
  });
```

This results in a change of color:

![Color Change In The Drawer Nav Example](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/06/color-change-in-drawer-nav.jpg?resize=1242%2C597&ssl=1)

## Passing parameters to screens

There are two simple steps to pass params to routes:

1. Pass params to a route by putting them in an object as a second parameter to the `navigation.navigate` function:
```jsx
this.props.navigation.navigate('RouteName', { /* params go here */ })
```
2. Read the params in your screen component:
```jsx
this.props.navigation.getParam(paramName, defaultValue)
```

## Conclusion

I hope that this article will jumpstart your use of the React Navigation package in your existing or future React Native projects. There’s a lot more that can be done; most of your needs will be met by this package. Feel free to explore more of the [documentation](https://reactnavigation.org/docs/en/getting-started.html) and to grab [the final code](https://github.com/emmyyusufu/react-navigation-demo) from my GitHub repo.
* * *
## Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps

[![LogRocket Dashboard Free Trial Banner](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png?resize=1200%2C677&ssl=1)](https://logrocket.com/signup/)

[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

[Try it for free](https://logrocket.com/signup/).
* * *
The post [Navigating React Native apps using React Navigation](https://blog.logrocket.com/navigating-react-native-apps-using-react-navigation/) appeared first on [LogRocket Blog](https://blog.logrocket.com).