cover
photo

Artem Pyvovar

Front-end Developer

London, UK

Front-End Developer with a lot of experience, adept at managing multiple projects while prioritizing code quality and meeting deadlines effectively.

JavaScriptTypeScriptReact.jsReact NativeNext.js

Summary

Front-End Developer (React.js, React Native, TypeScript) specializing in CRM, e-commerce, and diverse business models including C2B, B2B, C2C, B2E. Proficient in developing SaaS solutions. Experienced in Node.js, UX/UI design, and SEO. Participated in Scrum and Kanban software development methodologies, ensuring efficient project delivery. Bachelor of Engineering.

Information

  • LocationLondon, UK

Simple Guide to React Navigation Structure in React Native

In this blog-post, I'm going to share my experience on creating navigation structure in a React Native application and discuss how I personally organize navigation in my apps. While it may not seem excessively complicated, many make mistakes in the structure, leading to navigation issues later on. Let's get started:

Step 1: Project Setup

Make sure you set up your React Native development environment.
Create a new React Native (>= 0.63.0) project, which we'll name ReactNavigationStructureApp:

npx react-native init ReactNavigationStructureApp

Run the app with yarn ios.

Step 2: Installing React Navigation

To add React Navigation to our React Native application, refer to the official documentation. Please familiarize yourself with the official documentation.

Step 3: Design Analysis

As an example, I've chosen a freely available design in Figma (design link), which we'll use as a foundation for our project. Let's briefly go over what and how: One of the initial screens is the login/registration screen.

design

After successful registration, we navigate to the home screen.

design

The home screen has a tab bar present on various screens. There may be intermediate screens, such as onboarding or account settings, but we'll focus on the main navigation part.

Also in the design, we have nested screens, which means rendering a navigator inside a screen of another navigator. Read more

So, we've covered a small portion of screens from this design, but it's enough to determine the initial navigation structure.

Building Navigation Stacks:

To start, let's determine the number and types of root stacks required. In this example, we need 3 stacks (keeping in mind there may be more):

  1. Login & registration stack.

  2. Stack with the bottom tabs.

  3. Stack without the bottom navigation panel.

We create a navigation stack to which we add 3 screens. As a component, we'll nest another stack, making it easy to understand where to add new screens. If a screen displays a tab bar, add the screen to TabBarNavigator. For screens without a tab bar, add them to MainNavigator.

import { createStackNavigator } from '@react-navigation/stack';
 
const Stack = createStackNavigator();
 
function RootNavigator() {
  return (
    <Stack.Navigator screenOptions={{ headerShown: false }}>
      <Stack.Screen name={'AuthStack'} component={AuthNavigator} />
      <Stack.Screen name={'TabBarNavigator'} component={TabBarNavigator} />
      <Stack.Group>
        <Stack.Screen name={'MainStack'} component={MainNavigator} />
        {'...'}
      </Stack.Group>
    </Stack.Navigator>
  );
}

In RootNavigator, we also need to determine the initial screen. Create a boolean variable acting as a flag for whether the user is logged in. As a result, we get the following:

import { createStackNavigator } from '@react-navigation/stack';
 
const Stack = createStackNavigator();
 
function RootNavigator() {
  const isAuthed = false;
 
  return (
    <Stack.Navigator
      screenOptions={{ headerShown: false }}
      initialRouteName={isAuthed ? 'TabNavigator' : 'AuthStack'}>
      <Stack.Screen name={'AuthStack'} component={AuthNavigator} />
      <Stack.Screen name={'TabBarNavigator'} component={TabBarNavigator} />
      <Stack.Group>
        <Stack.Screen name={'MainStack'} component={MainNavigator} />
        {'...'}
      </Stack.Group>
    </Stack.Navigator>
  );
}

Meanwhile, in AuthNavigator, we can also explicitly set the initial screen. However, by default, the initial screen is the first screen in the navigation stack. You can leave the code as is, but for better practice, I recommend adding initialRouteName="SignInScreen".

In TabBarNavigator, it's a similar story. We need to create stacks, but now we use createBottomTabNavigator.

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
 
const Tab = createBottomTabNavigator();
 
function TabBarNavigator() {
  return (
    <Tab.Navigator
      screenOptions={{
        headerShown: false,
      }}>
      <Tab.Screen name="HomeStack" component={Home} />
      <Tab.Screen name="TopicsStack" component={Topics} />
      <Tab.Screen name="CreateTopicStack" component={CreateTopic} />
      <Tab.Screen name="NotificationsStack" component={Notifications} />
      <Tab.Screen name="ProfileStack" component={Profile} />
    </Tab.Navigator>
  );
}

However, note that if we have nested screens inheriting a tab, then the TabBarNavigator component will look different. For example,

 
function HomeStack() {
  return (
    <Stack.Navigator>
      {'...'}
    </Stack.Navigator>
  );
}
 
<Tab.Screen name="HomeStack" component={HomeStack} />
bbc

As we can see, this screen is a nested screen in the search tab. Therefore, for such structures, the above approach is suitable. But if a screen doesn't need to display the tab bar, it's not advisable to use tabBarVisible=boolean for your navigation stack. When navigating, your screen will jump, either hiding or adding the tab bar. All screens that don't need the tab bar should be placed in a separate navigation stack. For this, we created MainNavigator, where we'll place the screens.

In the end, we have a navigation structure like this.

bbc

That's it. Thanks for reading.