React navigation v5
Tags: reactnative, react, javascript, reactnavigation
Published: 2020-04-26 20:26:57

---
title: React navigation v5
published: true
description: Traversing the corners of your app with the helping hand of react-navigation
tags: #react-native, #react, #javascript, #react-navigation
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/3zx9wbxug7x1k82doto2.jpg
---


With the launch of [react native v5](https://www.npmjs.com/package/@react-navigation/native) about 3 months ago backed by neat [documentation](https://reactnavigation.org/docs/getting-started) making life easier with hooks usage and native transitions, we decided to revamp our current navigation.


## Problem:

Build a navigation system for a an app serving to showcase news content such as collections and stories with configurable paywall to facilitate pay per article / premium content across devices

## Design

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6znyw870kdwbzesmi2mo.png)

- Main screen consists of [bottom tab navigation](https://reactnavigation.org/docs/bottom-tab-navigator) of about 4 tabs
- Listing screens to showcase categories / sections
- Content screens to display content

## Architecture:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/x54wr12f2yxmc9mwtb3s.png)


<!-- App.js code -->

> App.js

The root of your application needs to be enclosed within a navigation controller, the children of which would be the stack of screens. This will helps us separate concerns b/w auth flows such as login stack and other flows in our case

```javascript
import { NavigationContainer, useLinking } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { enableScreens } from "react-native-screens";
```

```javascript
enableScreens();
const [initialState, setInitialState] = useState();
```

```javascript
     <NavigationContainer initialState={initialState} ref={ref}>
         <Stack.Navigator
           screenOptions={{
             headerShown: false
           }}
           initialRouteName="modalStack"
         >
           <Stack.Screen name="modalStack" component={ModalStack} />
           <Stack.Screen name="loginStack" component={LoginStack} />
         </Stack.Navigator>
       </NavigationContainer>
```


<!-- Modal stack code -->


> modal-stack.js

The stack is composed of multiple screens which relate in terms of genre in our case.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/o9xfr5222a6o4w0kso04.png)

The noticeable aspect is that the stacks are nested, `BottomTabStack` is nested within the modal stack and that will be the initial route where our app should land post launch

```javascript
import React from "react";
import { BottomTabStack } from "../bottom-tab-navigators/bottom-tab-stack";

import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { SCREEN_LIST, STACK_LIST } from "../../constants/screen-mapping";

/* Import screen components such as AuthorsScreen, StoryScreen ... */

const Stack = createNativeStackNavigator();

export const ModalStack = () => (
  <Stack.Navigator
    screenOptions={{
      headerShown: false
    }}
    initialRouteName={STACK_LIST.bottomTabStack}
  >
    <Stack.Screen name={SCREEN_LIST.authorScreen} component={AuthorsScreen} />
    <Stack.Screen name={SCREEN_LIST.storyScreen} component={StoryScreen} />
    <Stack.Screen name={SCREEN_LIST.bookMarkScreen} component={BookMarkScreen} />
    <Stack.Screen name={STACK_LIST.bottomTabStack} component={BottomTabStack} />
  </Stack.Navigator>
);

```


<!-- Bottom tab stack code -->

> bottom-tab-stack.js


```javascript

import React from "react";

import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";

/* Import necessary constants and components.. */

const Tab = createBottomTabNavigator();

const tabBarStyle = {
  activeTintColor: "blue",
  style: {
    paddingTop: 5
  }
};

const TabIcons = (focused, icon) => {
  const iconColor = focused ? "blue" : "black"; /* highlight with a diff color if focused */

  switch (icon) {
    case "home":
      return <HomeIcon color={iconColor} />;
    case "sections":
      return <SectionIcon color={iconColor} />;
    case "search":
      return <SearchIcon color={iconColor} />;
    case "my-app":
      return <MyAppIcon color={iconColor} />;
    default:
      break;
  }
};

export const BottomTabStack = () => (
  <Tab.Navigator tabBarOptions={tabBarStyle}>
    <Tab.Screen
      name={BOTTOM_TAB.bottomHomeTab}
      component={HomeScreen}
      options={{
        tabBarIcon: ({ focused }) => TabIcons(focused, "home"),
        title: "Home",
        tabBarTestID: "test-id-home" /* test id's for use by automation test tools */
      }}
    />
    <Tab.Screen
      name={BOTTOM_TAB.bottomCategoryTab}
      component={CategoryScreen}
      options={{
        tabBarIcon: ({ focused }) => TabIcons(focused, "sections"),
        title: "Sections",
        /* Unique identifier to target category tab */
        tabBarTestID: "test-id-categ"
      }}
    />
    <Tab.Screen
      name={BOTTOM_TAB.bottomSearchTab}
      component={SearchScreen}
      options={{
        tabBarIcon: ({ focused }) => TabIcons(focused, "search"),
        title: "Search",
        tabBarTestID: "test-id-search"
      }}
    />
    <Tab.Screen
      name={BOTTOM_TAB.bottomProfileTab}
      component={ProfileScreen}
      options={{
        tabBarIcon: ({ focused }) => TabIcons(focused, "my-app"),
        title: "My App",
        tabBarTestID: "test-id-profile"
      }}
    />
  </Tab.Navigator>
);


```



<!-- Login stack code -->

> login-stack.js

This stack abstracts the auth-flow.

```javascript

import React from "react";
import { createNativeStackNavigator } from "@react-navigation/native-stack";

/* Import screen components such as Login, SignUp ... */

const Stack = createNativeStackNavigator();

export const LoginStack = () => (
  <Stack.Navigator
    screenOptions={{
      headerShown: false
    }}
  >
    <Stack.Screen name={SCREEN_LIST.loginScreen} component={Login} />
    <Stack.Screen name={SCREEN_LIST.registrationScreen} component={SignUp} />
    <Stack.Screen name={SCREEN_LIST.forgotPasswordScreen} component={ForgotPassword} />
  </Stack.Navigator>
);


```


With that being set, we can begin surfing :surfer: through the screens


If we are navigating within a stack:

```javascript
navigation.navigate("<<screen_name>>", {<<key>>: <<val>>});
```

If we do need to navigate across stacks:

```javascript
navigation.navigate("<<stack_name>>", {  
                     screen: <<screen_name>>,
                     params: {<<param_key>> : <<param_val>>}
                   });
```

There are a lot of ground to cover with react-navigation such as [events](https://reactnavigation.org/docs/navigation-events/), [lifecycles] (https://reactnavigation.org/docs/navigation-lifecycle) and much more .. 

Will be dropping in a github repo link for an example soon :fire:

If you have questions, let us know in the comments and we are looking forward for your feedback :beers: