With react native we can build applications easily for both Android and iOS users using an almost “identical” codebase.
While this is an advantage, there are design elements that we must take into considerations when designing for both OSes.
Navigation element is one of the biggest items to consider in designing application for both OSes. There are articles in tutsplus and medium which discuss the topic further.
While iOS users are comfortable with tab bars as their navigation, Android users prefer drawer.
What are we building
Let’s build an application using react-native and react-navigation. This application will change its core navigational element depending on the OS it’s running in. While doing that, let’s try to get most of the screens and components shared!
The application would have 2 main routes which are external and internal routes.
External screens: contains all the screens for users who are not logged in.
Internal screens: contains the screens applicable to users who are logged in.
The main drawer or tab navigator will reside in the internal route.
Initializing the application
Check out debugging react native expo for basic react native setup if you have some issue getting up and running with react native.
Once we have the basic setup for react-native, we can go ahead and install react-navigation for our navigation elements.
react-native install react-navigation
Root Navigator
Let’s build the basic root navigator that gathers the internal and external screens together.
External Screens
The only screen we’ll create for external would be a LoginScreen.
LoginScreen contains a login button that would go to the internal screens on click. To do this, we’re calling navigator.navigate to “Internal” route.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
We’ll start off the internal screens with home screen that contains nothing but a text.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Root navigator will take a shape of stack navigator that gathers both external and internal screens together.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
We also need to update our App.js to load up this root navigator.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Now we have an external screen that goes to internal screen on a click of a button.
Nested stack navigator
With the root navigator in place, let’s start working with the drawer and tab navigator.
Let’s create another screen called About. This will allow us to switch to and from Home screen in the internal screen set.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
For iOS, we’ll wrap Home and About screen with a TabNavigator.
Let’s create an index (index.ios.js) file for internal route that contains this TabNavigator.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
For Android, we’ll create a DrawerNavigator. Let’s create the android index file (index.android.js) in internal route.
For DrawerNavigator, we have to render the navbar menu handle as well. We will be using react-native-vector-icon baked into expo for the handle icon.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
With the navigators created, let’s tune our internal screens, external screens and adjust our RootNavigator
Adjusting internal screens navigationOption
To have a good representation of the menu, we would like to add icons for our internal screens.
For tab bar, we would need to add the navigationOption tabBarIcon, and for drawer it’s drawerIcon.
Since we are deciding this by the OS, we can use Platform.select provided by react-native.
Let’s create a navigationHelper.js to help us with the configuration and update our navigationOption in Home.js and About.js.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Reset the navigation stack going into internal screens
We would also like to reset the navigation stack when user clicks on login button from external.
We want to do this to reset the stack back to 0 and prevent the back button from showing up in our tab or drawer screens.
We can do this by passing reset navigation action in the Login component instead of simply navigating.
We also want to ensure that login component does not render any header by doing header: null on navigationOption.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The last thing in our list is to update the RootNavigator to load up proper internal screens.
Change the import of Internal component to index, by importing the folder. React-native will automatically pick the correct file depending on the OS.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters