Navigation in PURE React Native
Tags: typescript, javascript, reactnative, silvenleaf
Published: 2022-05-05 09:15:31

Let's learn Navigation in PURE React Native System!!

# CHAPTER I: Root set up
Let's set up our core configurations for react native navigation
### Step 1: Install "@react-navigation/native"
First of all, install the core package of react navigation
```bash
npm install @react-navigation/native
```
Now what?
### Step 2: Install core utility packages
We will now install the core two utility packages for react native navigation. These are ***"react-native-screens"*** and ***"react-native-safe-area-context"***

(If expo, install them using expo, if not, install them using npm)
```bash
npm install react-native-screens react-native-safe-area-context
```
Now for pure react native apps, ***"react-native-screens"*** package requires one additional configuration step to properly work on Android devices. This change is required to avoid crashes related to View state being not persisted consistently across Activity restarts. What and How?

***
(For PURE React Native)
Edit ***"MainActivity.java"*** file which is located in ***"android/app/src/main/java/{Your_package_name}/MainActivity.java"***. Add the following code to the body of the ***"MainActivity"*** class
```java
@Override  
protected void onCreate(Bundle savedInstanceState) {  
super.onCreate(null);  
}
```
And make sure to add an ***"import"*** statement at the top of this file
```java
import android.os.Bundle;
```
***

### Step 3: Wrapping our App in NavigationContainer
Finally, let's wrap our app in NavigationContainer
```typescript
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import HomeScreen from './NeiXin/screens/HomeScreen';

const App = () => {
  return (
    <NavigationContainer>
      <HomeScreen/>
    </NavigationContainer>
  );
};

export default App;
```
***
# CHAPTER II: Utility set up
Let's learn how to set up drawer and/or stack navigator.

### Step 1: Install utility packages
You need to install ***"react-native-gesture-handler"*** and ***"react-native-reanimated"***  utility packages. It's same for all (drawer, stack and tab) navigators! Let's install them
(If expo, install them using expo, if not, install them using npm)
```bash
npm install react-native-gesture-handler react-native-reanimated
```
Now for PURE React Native Apps, we need to put this following line at the ***extreme top*** of our entry file (for me it is App.tsx file). We have to make sure it's at the top and there's nothing else before it
```typescript
import 'react-native-gesture-handler';
```
Great we finished the utility set up. Let's now install the core packages depending on our Navigators :)

### Step 2: Reanimated 2 configuration
For PURE React Native app, you might get an error related to ***"Reanimated 2"*** . For this we need to configure it properly. How? Let's tag along!

(for more info check this one out [reanimated 2 configuration](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation/))

##### Part 1:
In babel.config.js add this 
(NOTE: Reanimated plugin has to be listed last)
```typescript
  module.exports = {
      ...
      presets: [...],
      plugins: [
          ...
          'react-native-reanimated/plugin' //make sure this is always the last line
      ],
  };
```
##### Part 2: Turn on Hermes engine
Turn on Hermes engine by editing ***"android/app/build.gradle"***
```gradle
project.ext.react = [
  enableHermes: true  // <- here | clean and rebuild if changing
]
```

##### Part 3: Update MainApplication.java
Update the ***"android/app/main/java/{Your_package_name}/MainApplication.java"***
```java
  import com.facebook.react.bridge.JSIModulePackage; // <- add
  import com.swmansion.reanimated.ReanimatedJSIModulePackage; // <- add
  ...
  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
  ...

      @Override //find these four lines, these already exist, we need to add the next 4 lines after these four lines
      protected String getJSMainModuleName() {
        return "index";
      }

      @Override //add these four lines after the above four lines
      protected JSIModulePackage getJSIModulePackage() {
        return new ReanimatedJSIModulePackage();
      }
    };
  ...
  ```
  You can refer to [this diff](https://github.com/software-mansion-labs/reanimated-2-playground/pull/8/commits/71642dbe7bd96eb41df5b9f59d661ab15f6fc3f8) that presents the set of the above changes made to a fresh React Native project.

##### Part 4: Try running
Try running your app, if still get the error, remove the cache using this command
```bash
npx react-native start --reset-cache
```
It'll restart your app removing the cache. Now optionally you can stop it and restart your app with this command
```bash
npm run android
```
Hope it helps :)

***
# CHAPTER III: Specific Navigators
Let's learn how to use Drawer, Stack and Tab navigators. We'll install our specific navigators with this command

#### (If Drawer Navigation)
```bash
npm install @react-navigation/drawer
```
#### (If Stack Navigation)
I prefer this because it is said to be significantly more customizable
```bash
npm install @react-navigation/stack
```
[OR]
I don't prefer it much because it is said to be inpractible to impossible to customize a lot of things
```bash
npm install @react-navigation/native-stack
```
#### (If Bottom Tab Navigation)
```bash
npm install @react-navigation/bottom-tabs
```

### Drawer Navigation
```typescript
const Drawer = createDrawerNavigator();
function RootDrawer() {
  return (
    <Drawer.Navigator>
      <Drawer.Screen name="Home Page" component={HomeScreen}/>
      <Drawer.Screen name="About Page" component={AboutScreen}/>
    </Drawer.Navigator>
  )
}
```
***
### Stack Navigation
```typescript
const Stack = createStackNavigator();
function RootStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Home Page" component={HomeScreen}/>
      <Stack.Screen name="About Page" component={AboutScreen}/>
    </Stack.Navigator>
  )
}
```
***
### Bottom Tabs Navigation
```typescript
const Tab = createBottomTabNavigator();
function RootBottomTab() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home Page" component={HomeScreen}/>
      <Tab.Screen name="About Page" component={AboutScreen}/>
    </Tab.Navigator>
  )
}
```
***

# What's NEXT?
#### 1. Async Storage with Pure React Native
#### 2. Project with Pure React Native
#### 3. More on App Development
#### 4. How to deploy to playstore
#### 5. Insane stuff with JavaScript/TypeScript
#### 6. Writing Automated Tests for any Server
#### 7. How to create an Android APP with NO XP with Expo
(including apk generating)


# Got any doubt? 
Drop a comment or Feel free to reach out to me @SilveLEAF on Twitter or [Linkedin](https://www.linkedin.com/in/silvenleaf/)

Wanna know more about me? Come here! 
[SilvenLEAF.github.io](https://SilvenLEAF.github.io)