How to use React Navigation v5 in React Native

Published on
5 mins read
--- views
Authors

Overview

In an App, the most common way of page navigation is using Tab bar and header, while the official third party library recommended by React Native is react-navigation. React Navigation have already released version 5.x, which is quite different from the previous version, but it is more convenient to use. This article mainly explains the usage of react navigation 5.0 and above.

Installation

Core Library

terminal
Command line
# NPM
npm install @react-navigation/native

# Yarn
yarn add @react-navigation/native

Dependencies

terminal
Command line
# NPM
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
#Yarn
yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

From React Native 0.60 and higher, linking is automatic. So you don’t need to run react-native link. If you’re on a Mac and developing for iOS, you need to install the pods (via Cocoapods) to complete the linking.

terminal
Command line
npx pod-install ios

Now, we need to wrap the whole app in NavigationContainer. Usually you'd do this in your entry file, such as index.js or App.js:

react
import 'react-native-gesture-handler';
import \* as React from 'react';
import { NavigationContainer } from '@react-navigation/native';

export default function App() {
  return (
    <NavigationContainer>{/* Rest of your app code */}</NavigationContainer>
  );
}

Note: If you also use the Redux framework, you need to place the provider in the outermost layer and the NavigationContainerin the secondary layer, similar to the following:

react
export default class App() {
  return (
    <Provider store={store}>
      <NavigationContainer>
        {/* Screen configuration */}
      </NavigationContainer>
    </Provider>
  );
}

Usage

React Navigation has several navigation modes: Stack Navigation , Tab Navigation and Drawer Navigation . Here I mainly talk about Stack Navigation and Tab Navigation.

Stack Navigation

Stack Navigation is relatively simple to use. It only needs to encapsulate the page components that need to be navigated Stack.ScreenAnd then wrapped in Stack Navigator That’s it. The top one Stack.Screen is the default page.

react
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen key="Home" name="Home" component={HomeScreen} />
      </Stack.Navigator>
      <Stack.Screen key="detail" name="Detail" component={DetailScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

It can also be in the Stack.Screen There are two ways to set the properties of the navigation bar. One is with route parameter, and the other is set it directly.

react
/* with route parameter */
<Stack.Screen
    key={name}
    name={name}
    component={component}
    options={({route}) => ({
        headerTitle: route.name,
        headerStyle: {
            backgroundColor: '#01aaff',
        },
        headerTintColor: '#fff',
        headerTitleStyle: {
            fontWeight: 'bold',
        },
        headerRight: () => (
            <Button
              onPress={() => alert('This is a button!')}
              title="Info"
              color="#fff"
            />
          ),
        headerShown: true
    })}
/>
/* set options props directly */
<Stack.Screen
    key={name}
    name={name}
    component={component}
    options={{
        headerTitle: 'name',
        headerStyle: {
            backgroundColor: '#01aaff',
        },
        headerTintColor: '#fff',
        headerTitleStyle: {
            fontWeight: 'bold',
        },
        headerRight: () => (
            <Button
              onPress={() => alert('This is a button!')}
              title="Info"
              color="#fff"
            />
          ),
        headerShown: true
    }}
/>

When you need to jump to other pages, you can use navigation parameter to navigate.

react
function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button
        title="Go to Details"
        onPress={() => {
          /* 1. Navigate to the Details route with params */
          navigation.navigate('Details', {
            itemId: 86,
            otherParam: 'anything you want here',
          });
        }}
      />
    </View>
  );
}

If the page is created in class mode, the code will look like this:

react
export default class HomeScreen extends Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Home Screen</Text>
        <Button
          title="Go to Details"
          onPress={() => {
            this.props.navigation.navigate('Details', {
              itemId: 86,
              otherParam: 'anything you want here',
            });
          }}
        />
      </View>
    );
  }
}

Note: We can be used navigation.navigate or navigation.push . If navigate , it will find out whether there is a route with the same name in the current stack. If not, it will create a new route and jump. If push will create a new route and jump directly, that is, it can jump to the same page repeatedly.

react
// Go back to the previous route in history.
navigation.goBack();
// Go back to the first screen in the stack
navigation.popToPop();

More actions please check CommonActions

Tab Navigation

First, you need to install the corresponding library

terminal
Command line
# NPM
npm install @react-navigation/bottom-tabs

# Yarn
yarn add @react-navigation/bottom-tabs

The *Tab.Navigator *is used in a similar way. You need to package these page components into Tab.Screen.

react
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen name="Home" component={HomeScreen} />
        <Tab.Screen name="Settings" component={SettingsScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

The Tab.Navigator properties can be set as follows:

react
<Tab.Navigator
  screenOptions={({ route }) => ({
    tabBarIcon: ({ focused, color, size }) => {
      let iconName;

      if (route.name === 'Home') {
        iconName = focused
          ? 'ios-information-circle'
          : 'ios-information-circle-outline';
      } else if (route.name === 'Settings') {
        iconName = focused ? 'ios-list-box' : 'ios-list';
      }
      return <Ionicons name={iconName} size={size} color={color} />;
    },
  })}
  tabBarOptions={{
    activeTintColor: 'tomato',
    inactiveTintColor: 'gray',
  }}
>
  <Tab.Screen name="Home" component={HomeScreen} />
  <Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>

Nesting navigators

Nesting navigators means rendering a navigator inside a screen of another navigator, for example:

react
function Home() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Feed" component={Feed} />
      <Tab.Screen name="Messages" component={Messages} />
    </Tab.Navigator>
  );
}
function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={Home} />
        <Stack.Screen name="Profile" component={Profile} />
        <Stack.Screen name="Settings" component={Settings} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

Check the docs for more details: https://reactnavigation.org/docs/getting-started