When I was first learning React Native, I had three weeks to get a mobile application up and running. I got started with Expo (which I do recommend to those starting out) and used the React Navigation library to handle routing and navigation, as is recommended by Expo.
At some point, I felt the pressure and quickly put out something that while worked, it did not feel like a mobile app. I should have slowed down to take the time to understand how all of the different types of navigators work together to build a smooth "app like" experience.
In particular, I had bottom tabs and wanted each of those tabs to also be able to function independently with its own navigation. And since I had authentication flow, I utilized a switch navigator to prevent users from going back to the sign-in screen after logging in. Note: React Navigation’s latest 5.x version has removed the Switch Navigator because you can now dynamically define and alter the screen definitions of a navigator, rendering Switch Navigator unnecessary).
So while I did have those bottom tabs, there was a lot of conditional rendering happening directly in the screens, and there were no automatic back buttons produced in the header because there was no stack to be had. I had what seemed like a web app masquerading as a mobile app. When you have to create your own back buttons in a mobile app, it’s time to reset.
I put off fixing the navigation for weeks and instead focused on building out other user features. But of course I couldn't ignore it forever and finally sat down and figured it out (otherwise this would be the end of the blog post).
I’m writing this today to share with you what I learned so that I can possibly help someone who was in my position when I first started out (or I go back in time without my memories and need to reference how to do this again).
Creating stack navigators first for each of the bottom tabs is key, as it essentially creates navigation stacks within each tab and can bring you to a new screen within that tab.
The above code demonstrates how to set up a stack utilizing React Navigation's latest 5.x syntax. You will need to import
@react-navigation/stack. React Navigation 5 has changed a lot, including a new component based API and going with scoped packages to distinguish from v4 and v5 packages.
You can still customize your stacks.
Stack.Navigator accepts props like
initialRouteName that renders that route on first load of the navigator. For the individual screens in the stack, there is the
options prop that can set the title and other configurations.
Once you've created the stack navigators for each tab, then you can create the bottom tab navigation as seen below.
Similar to customizing a stack navigator, there are some properties that are set when you initialize the tab navigator (such as
initialRouteName) and other properties that are customized with each screen using the
options prop. I've included above how to customize a tab name with
tabBarLabel and icon with
Once your stack and tab navigators have been initialized, those will all have to be wrapped in
NavigationContainer, which replaces
createAppContainer from version 4.
NavigationContainer is a component that manages your navigation tree and contains the navigation state, and you would usually want to render this component at the root of your app. When dealing with authentication flow, it is now done declaratively, making your code easier to debug.
And to tie it all together, here is the all of the above code that would make up the navigation for a simple app:
Once it all clicked for me, I created a new branch in my repo to test it out and I was good to go. All of that agony for 15 minutes of work. I was able to access the header and could change the header name, and most importantly, when I navigated to a new screen and it was pushed onto the stack, I got that back button.
I had never been so happy seeing a back button. Looking back now, I can laugh at how simple it was all along.