Beruflich Dokumente
Kultur Dokumente
Navigation
Shovon Follow
Feb 18, 2018 · 7 min read
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.
Preface
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.
Introduction
You can implement React Navigation both with Redux and without
Redux. Since we are starting from scratch, we will start with “without
Redux”.
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.
Problems
I will work with blank screens and just focus on the solutions of the
following requirements —
1. Navigating to a screen
Setup
Hers’s a prototype of the app —
App prototype
AppStackNav
|- HomeScreen
|- LoginScreen
|- SignupScreen
|- AppDrawerNav
|- NewsStackNav
| |- NewsTabNav
| | |- NewsGlobalScreen
| | |- NewsLocalScreen
| |- NewsDetailScreen
|- AccountTabNav
|- AccountProfileScreen
|- AccountSettingScreen
Code
We will use all our examples from this repository(for react-navigation
v1). Let’s code.
. . .
Navigating to a screen —
// navigators/AppStackNav.js
const AppStackNav = StackNavigator({
Home: {
screen: Home,
navigationOptions: {
header: null
}
},
Login: {
screen: Login,
navigationOptions: {
header: null
}
}
});
this.props.navigation.navigate("Login")
Or
this.props.navigation.dispatch(
NavigationActions.navigate({ routeName: "Login" })
);
. . .
Similarly for,
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.
. . .
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.js
this.props.navigation.dispatch(
NavigationActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName:
"Dashboard" })]
})
);
Here reset ting with index: 0 would make the screen passed in
routeName as the initial screen, removing all previous screens from the
stack.
AppSwitchNav
|- UnauthStackNav
|- HomeScreen
|- LoginScreen
|- SignupScreen
|- AppDrawerNav
|- NewsStackNav
| |- NewsTabNav
| | |- NewsGlobalScreen
| | |- NewsLocalScreen
| |- NewsDetailScreen
|- AccountTabNav
|- AccountProfileScreen
|- AccountSettingScreen
. . .
// screens/Dashboard.js
render() {
return <AppDrawerNav navigation={this.props.navigation}
/>;
}
}
. . .
To pass any data in the destination screen, you can pass your data in
params .
// screens/NewsLocal.js
this.props.navigation.setParams({
key1: 'value1',
key2: 'value2',
})
this.props.navigation.getParam('KeyToFind',
'OptionalDataToShowIfKeyNotFound')
. . .
this.props.navigation.goBack()
. . .
// screens/Dashboard.js
this.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
. . .
this.props.navigation.goback(’keyOfTheVisitedScreenToGo’)
You can manually set key when going to a screen. So whenever you
want to go back from that screen, you have to pass that key.
. . .
As of v3 there are few other changes that you should know about
(which might feel unexpected).
Navigating back in navigator —
App
|- Stack1
|- Screen1
|- Screen2
|- Screen3
|- Stack2
|- Screen4
|- Screen5
|- Screen6
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.
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.
. . .
Conclusion
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!