How to properly navigate with React Navigation (2024)

How to properly navigate with React Navigation (3)

EDIT: When this article was written, react-navigation was version 1. There have been many changes in it when it reached version 3. Some parts of the article have been updated accordingly with adding few extra details.

In this article, you will learn various ways to navigate in your application using React Navigation. I will assume that you know the basics of React Navigation. I will show you how to properly set, access and pass properties in different screens to make navigation easy. Make sure you have read the official docs before starting this to get accustomed with this library.

React Navigation is not the only contender for navigating in a mobile application, you can also find other navigation libraries, namely React Native Router Flux, React Native Navigation and Native Navigation.

The last two plugin are “native” navigation i.e. they are built on top of the Android and iOS platform navigational components, unlike React Navigation which is a JS based solution.

If you are confused whether to use a JS based solution or a native one, maybe this post can help you (brace for a long read!).

You can implement React Navigation both with Redux and without Redux. Since we are starting from scratch, we will start with “without Redux”.

We will go with building a news application. I will name it FuNA (Futuristic News Application).

Before we begin, here’s what you need to know about React Navigation —

For navigation you need a Navigator and there are three different types of Navigator in it — StackNavigator, TabNavigator and DrawerNavigator.

As of v3, there is a new navigator named SwitchNavigator.

Whenever you register a component with any of these Navigators, then only navigation prop is passed to the registered component. That prop is responsible for all navigation inside the application.

I will work with blank screens and just focus on the solutions of the following requirements —

  1. Navigating to a screen
  2. Navigating to nested Child screen from Parent screen
  3. Navigating to nested Child screen from a different Parent screen
  4. Navigating to nested Child screen from a Child screen of different Parent
  5. Accessing navigation in a Component
  6. Resetting screen to first Parent screen, from a nested screen

Hers’s a prototype of the app —

How to properly navigate with React Navigation (4)

The screens will be arranged like this —

AppStackNav
|- HomeScreen
|- LoginScreen
|- SignupScreen
|- AppDrawerNav
|- NewsStackNav
| |- NewsTabNav
| | |- NewsGlobalScreen
| | |- NewsLocalScreen
| |- NewsDetailScreen
|- AccountTabNav
|- AccountProfileScreen
|- AccountSettingScreen

And, here’s what the final app will look like—

How to properly navigate with React Navigation (5)

We will use all our examples from this repository(for react-navigation v1). Let’s code.

Navigating to a screen —

If you have a simple StackNavigator like below,

// navigators/AppStackNav.jsconst AppStackNav = StackNavigator({
Home: {
screen: Home,
navigationOptions: {
header: null
}
},
Login: {
screen: Login,
navigationOptions: {
header: null
}
}
});

Then to navigate to Login from Home , you would simple call

this.props.navigation.navigate("Login")

Or

this.props.navigation.dispatch(
NavigationActions.navigate({ routeName: "Login" })
);

Similarly for,

  • Navigating to nested Child screen from Parent screen
  • Navigating to nested Child screen from a different Parent screen
  • Navigating to nested Child screen from a Child screen of different Parent

just pass the required routeName in navigate function.

this.props.navigation.navigate("routeNameOfScreenToGo") 

In v1, for a successful screen change, the routeName had to be accessible in the screen from where you were calling the navigate function i.e. we had to make custom actions if we had to go to any specific nested/cousin screens.

In v3, navigate function itself determines how to navigate to passed routeName.

Resetting to a screen —

Now suppose, once someone successfully logs in, you would like to prevent them to go back to login/signup screen. Here’s how that would be possible

// screens/Login.jsthis.props.navigation.dispatch(
NavigationActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: "Dashboard" })]
})
);

Here resetting with index: 0 would make the screen passed in routeName as the initial screen, removing all previous screens from the stack.

As of v3, due to introduction of SwitchNavigator we can change our navigation setup to following —

AppSwitchNav
|- UnauthStackNav
|- HomeScreen
|- LoginScreen
|- SignupScreen
|- AppDrawerNav
|- NewsStackNav
| |- NewsTabNav
| | |- NewsGlobalScreen
| | |- NewsLocalScreen
| |- NewsDetailScreen
|- AccountTabNav
|- AccountProfileScreen
|- AccountSettingScreen

SwitchNavigator resets routes to their default state when you switch away from UnauthStackNav to AppDrawerNav .

Accessing navigation in a Component —

If you use a Component to render a navigator, then you have to keep in mind to pass that navigator’s router to Component’s router and pass the navigation prop to the Component navigation (since that Component is not registered as any navigator, it will not receive any navigation prop automatically).

// screens/Dashboard.jsimport React, { Component } from "react";
import AppDrawerNav from "../navigators/AppDrawerNav";
export default class Dashboard extends Component {
static router = AppDrawerNav.router;
render() {
return <AppDrawerNav navigation={this.props.navigation} />;
}
}

Passing ans accessing data from among screens —

To pass any data in the destination screen, you can pass your data in params .

// screens/NewsLocal.jsthis.props.navigation.navigate("NewsDetail", { topic: "React Navigation" })

To pass data in the current screen, you can call setParams

this.props.navigation.setParams({
key1: 'value1',
key2: 'value2',
})

To access data passed in params in the destination screen, you can access it in props.navigation.state.params .

You can also call getParam

this.props.navigation.getParam('KeyToFind', 'OptionalDataToShowIfKeyNotFound')

In our case, accessing props.navigation.state.params.topic would give React Navigation in the destination screen.

Going back from a screen to previous screen —

this.props.navigation.goBack()

Resetting screen to first Parent screen, from a nested screen —

Let’s consider a situation when someone logs out of the application. In that case you would want them to go to Home (assumed) without being able to go back. Here’s how you can do that.

// screens/Dashboard.jsthis.props.navigation.dispatch(
NavigationActions.reset({
index: 0,
key: null,
actions: [NavigationActions.navigate({ routeName: "Home" })]
})
)

Notice the key: null that has been added for this case. This generally should not be required but when you are in a child screen and want to reset to parent screen, navigator cannot identify other routes than the routes accessible to current screen.

This means if you are in NewsGlobal and you click logout icon (in our app), then the only available routes the navigator finds is NewsTabNav and NewsDetail . As of now there is no solution for this, except this workaround key: null .

You can read more about this issue here.

As of v3, reset is only available in StackActions , which means you can only call this function from a StackNavigator .

Going back more than one screen —

Suppose if you traversed screen in this fashion ScreenAScreenBScreenC , then if you want to goBack from ScreenC to ScreenA , you would have to pass thekey of that screen as params in goBack

this.props.navigation.goback(’keyOfTheVisitedScreenToGo’)

You can manually setkey when going to a screen. So whenever you want to go back from that screen, you have to pass that key.

You can read more about this here.

As of v3 there are few other changes that you should know about (which might feel unexpected).

Navigating back in navigator —

To navigate in a navigator if you use navigate , then going back will always take you to initialRoute of that navigator. You can prevent that in drawer and tab by providing backBehavior: ‘none' but that gives rise to different cases too.

If you have the following setup —

App
|- Stack1
|- Screen1
|- Screen2
|- Screen3
|- Stack2
|- Screen4
|- Screen5
|- Screen6

And you are currently on Screen3 . Now when you call navigate('Screen6') you will go to Screen6 . From here if you go back normally, you will first go to Screen4 then to Screen3 .

If you need navigating back from Screen6 to Screen3 you need to call dispatch function with custom action .

this.props.navigation.dispatch(
NavigationActions.navigate({
routeName: 'Stack2',
action: NavigationActions.navigate({
routeName: 'Screen6',
})
})
)

This works because when you pass action it prioritises child action than the top level action. See details in this PR.

For this case you can also manually go back via props.navigation.goBack(null) or props.navigation.pop() .

You should also keep in mind similar case does not work for DrawerNavigator.

I have made a Snack Expo where you can find various cases where simply calling props.navigation.goBack() or pressing hardware back button (without adding event handler) would not take you back as you expect them to.

Learning React Navigation is easy. Initial stages are easier too. But as an app grows more complex it becomes necessary to make a right choice in the structure of the navigation of the app as you would not be able to make it work with different type of navigator(like whether to register a component inside a stack or a tab or a drawer).

Before going into React Navigation you should keep in mind that, it is still new and may contain bugs and side effects. It can happen that you got stuck in one problem for long hours. So before going into any navigation plugin do your research thoroughly.

That’s all for now. Hope you find this useful. If you think this can help someone else too, pass it on.

Peace!

How to properly navigate with React Navigation (2024)
Top Articles
Latest Posts
Article information

Author: Dr. Pierre Goyette

Last Updated:

Views: 6347

Rating: 5 / 5 (70 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Dr. Pierre Goyette

Birthday: 1998-01-29

Address: Apt. 611 3357 Yong Plain, West Audra, IL 70053

Phone: +5819954278378

Job: Construction Director

Hobby: Embroidery, Creative writing, Shopping, Driving, Stand-up comedy, Coffee roasting, Scrapbooking

Introduction: My name is Dr. Pierre Goyette, I am a enchanting, powerful, jolly, rich, graceful, colorful, zany person who loves writing and wants to share my knowledge and understanding with you.