Navigate between pages in a React Native App

Navigate between pages in a React Native App

In this blog, we are going to talk about how we can navigate to and fro in React Native Applications. We will be learning about navigation by building a project and see how navigation works in react native.

We are going to learn,

  • Setting up a project.
  • Installing Package.
  • How navigation works in react native.
  • Working with navigation.
  • Passing data from one screen to another while navigating.

Setting up a project

1. To start off with first let's create a project. To create a project first run,

expo init

2. Then we will choose a template from the following,

Navigate between pages in a React Native App

we will select, blank as an option.

3. Then we will setup the name and slug,

Navigate between pages in a React Native App

and finally, we will add Yarn Dependency and will complete the setup.

4. Now, let's navigate to the folder using and run the app in emulator or real device using,

yarn start

5. It will open the browser and there we can select Run on Android Device/Emulator to run the app. After running the app will look like this,

Navigate between pages in a React Native App

Now, our App is up and running.

Note: Some of you might encounter a screen like,
Navigate between pages in a React Native App

This means we don't have an SDK version specified in the app.json file. To fix this, let's navigate to app.json file of the project and add,

"sdkVersion": "36.0.0",

And now save the file and run the app, we would have solved the error.

Installing Package

Now, we will install the required package for navigation. For this project, we are going to use React Navigation. You can find it here .

To install the package we will use,

yarn add @react-navigation/native

and since we have a project managed by the expo, we will be needing to install a few extra packages as well. To install them we will run,

expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view

Now, we are done installing the packages. Let us now write some code.

How navigation works in React Native

In React Native, let' see we have three screens. Home, List and Dashboard screen and the sequence is,

Home -> List -> Dashboard.

And when we press the back button, the sequence is reversed like,

Dashboard -> List -> Home

But, how does navigation works?

In React Native the navigation in the app works on a concept of a stack. Imaging the use case, where we need to go from Home to Dashboard screen then and Home screen is the first screen user sees when they come to the app. Then,

We have a stack with only one screen and it will look like,

Navigate between pages in a React Native App

Now, let's say we navigated to List Screen and then to Dashboard. Then both the screen will be added to the stack like,

Navigate between pages in a React Native App

This is how screens get added to the stack when we keep navigating to different screens.

Now, let's say we press the back button from Dashboard Screen then the Dashboard Screen gets popped out of the stack and then the list screen is displayed.

Navigate between pages in a React Native App

This is how navigation works. When we open a new screen the screens get added to the stack and when we navigate back the screen pops out of the stack.

Working with Navigation

Now, in the project let's create a folder src , and inside that create two more folders screens and routes .

src
 --screens
 --routes

Inside, routes we will first create a navigator.js file. We will also install a new package to manage the navigation stack. To install it we will use,

yarn add @react-navigation/stack

In the navigator.js file, we will add,

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import  Home from '../screen/home'
import  List from '../screen/list'
import  Dashboard from '../screen/dashboard'



const AppStack = createStackNavigator();
export default function Navigator(){

    return (
    <NavigationContainer>
    <AppStack.Navigator screenOptions={{ headerShown: true }} >
    <AppStack.Screen name="Home" component={Home} />
    <AppStack.Screen name="List" component={List} />
    <AppStack.Screen name="Dashboard" component={Dashboard} />
    </AppStack.Navigator>

    </NavigationContainer>
    );
}

In the above code, we first created a createStackNavigator which is responsible for creating the routes and it contains the Screen and Navigator as property.

Then we added, NavigationConstainer component which is responsible for holding the navigation state for the app and inside it we added the AppStack.Navigator and AppStack.Screen components.

AppStack.Navigator takes Screen component with a name and component property. We will access the navigation tree in the app using this name property.

Now, in the screens package let's create three files.

home.js, list.js and dashboard.js

Inside home.js, we will add the following

import React from 'react';
import { Text, View, Button } from 'react-native';
import { useNavigation } from '@react-navigation/native';


export default function Home() {
    
    const navigation = useNavigation();

    function navigateToList() {
        navigation.navigate("List");
    }
    
    return (
            
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
    <Text> Home Screen </Text>
    <Button title="Open List Screen"
    onPress= {()=>navigateToList()}
    />
    
    </View>
    );
}

In this, we added a text and button in the view and onPress of the button I call a function navigateToList() . Inside the function, we use the navigation to navigate to the name "List" which we created in Navigator.js.

useNavigation() gives us access to the navigation object which returns the navigation props

Similarly, we will modify the other two screens.list.js will look like,

import React from 'react';
import { Text, View, Button } from 'react-native';
import { useNavigation } from '@react-navigation/native';


export default function List() {
    
    const navigation = useNavigation();

    function navigateToDashboard() {
        navigation.navigate("Dashboard");
    }
    
    return (
            
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
    <Text>List Screen</Text>
    <Button title="Open Dashboard"
    onPress= {()=>navigateToDashboard()}
    />
    
    </View>
    
    );
}

and lastly, in dashboardScreen.js,

import React from 'react';
import { Text, View,Button } from 'react-native';
import { useNavigation } from '@react-navigation/native';


export default function Dashboard() {
    const navigation = useNavigation();

    function onBackPressed(){
        navigation.goBack()
    }
    return (
            
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
    <Text>Dashboard Screen</Text>
    <Button title="Click to go Back"
    onPress= {()=>onBackPressed()}
    />
    </View>
    
    );
}

Here, in dashboard.js you can see I have added navigation.goBack() in the press of the button. When goBack() gets called its pops out the dashboard screen from the stack and goes to the previous screen in the dashboard.

So, now when I run the app we will see the following flow being executed,

Navigate between pages in a React Native App

Here, in the above picture, you can see that on the second and third screen you can see the back arrow button is added by default and on click of the screen is popped out of the stack to navigate to the previous screen.

This is how we can navigate between different screens in the app.

Passing data from one screen to another while navigating.

How can we pass data from home.js to list.js?

In home.js, first, we will pass some data to the navigation object like,

function navigateToList() {
    
    navigation.navigate("List",{"name":"Himanshu"});
    
}

Here, I am passing a parameter with a key "name" and value as "Himanshu" which will be passed to the list.js file.

And in list.js file, to access the data, we will first create route like,

const route = useRoute();

Here, useRoute() returns the route prop of the screen it's inside which we will use to access the data which we passed from home.js

And now to access the key name we will use,

route.params.name

Here, in the route.params return the data for this route and we get the value Himanshu by added the key. If you see the code in home.js file, we pass a value with the key " name ". So, that is why we are getting the value using the name key.

The complete code looks like,

import React from 'react';
import { Text, View, Button } from 'react-native';
import { useRoute,useNavigation } from '@react-navigation/native';


export default function List() {
    const navigation = useNavigation();
    const route = useRoute();

    function navigateToDashboard() {
        navigation.navigate("Dashboard");
    }
    return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
    <Text>{route.params.name}</Text>
    <Button title="Open Dashboard"
    onPress= {()=>navigateToDashboard()}
    />
    </View>
    );
}

where, useRoute() is part of @react-navigation/native package.

This is how we can navigate to and fro in a React Native app.

Happy learning.

Team MindOrks :)