React Navigation 5.0.0

React Navigation Version 5.0

tl;dr

Updated on 18 March 2020

Giving a try on React Navigation version 5.0 – declarative way to implement navigation in React Native.

Let’s start

#1 Prerequisites

@ Let’s start

Generate a new project using react-native cli.

$ react-native init TryReactNavigationV5

or

$ react-native init TryReactNavigationV5 --version [version-number]

@ Install React Navigation

** yarn or npm, depend on your project package management.

Install react-navigation using following command. Take note that now react-navigation use the new package-name.

$ yarn add @react-navigation/native
$ yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

@ Install React Navigation Stack

Starting React Navigation version 4. The StackNavigator, DrawerNavigator BottomTabNavigator or etc has been isolated as standalone package. Thus, in order to use specific Navigator, one must install from npm.

  • createStackNavigator
$ yarn add @react-navigation/stack
  • createDrawerNavigator
$ yarn add @react-navigation/drawer
  • createBottomTabNavigator
$ yarn add @react-navigation/bottom-tabs
  • createMaterialBottomTabNavigator
$ yarn add @react-navigation/material-bottom-tabs react-native-paper react-native-vector-icons

react-native-vector-icons installation guide.

  • createMaterialTopTabNavigator
$ yarn add @react-navigation/material-top-tabs react-native-tab-view
  • iOS (Installed require library using Cocoapods)
cd ios && pod install && cd ..

To complete the installation of react-native-gesture-handler.

Import react-native-gesture-handler in the entry file – App.js or index.js depend on your file structure. The first line of file before anything else.

import 'react-native-gesture-handler';

...

@ Error from react-native-reanimated

You may probably hitting similar error, after installing the react-native-reanimated and try to run react-native run-android.

This is due to react-native-reanimated library required an extra properties – supportLibVersion in projectRootFolder/android/build.gradle.

Solution,

ext {
    buildToolsVersion = "28.0.3"
    minSdkVersion = 16
    compileSdkVersion = 28
    targetSdkVersion = 28
    supportLibVersion = "28.0.0" // Add this line to resolve the error
}

@ React Navigation – declarative way

// App.js
import React, { useState } from "react";
import {
  View,
  TextInput,
  Text,
  Button,
  StyleSheet,
  ActivityIndicator,
} from "react-native";
import { NavigationProp } from "@react-navigation/core";
import { NavigationNativeContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";

const Stack = createStackNavigator();

const App: () => React$Node = () => {
  const [token, setToken] = useState("");
  const [loading, setLoading] = useState(false);

  if (loading) {
    return (
      <View style={style.container}>
        <ActivityIndicator size="large" />
      </View>
    );
  }

  return (
    <NavigationNativeContainer>
      <Stack.Navigator initialRouteName={token ? "Home" : "Login"}>
        <Stack.Screen
          name="Login"
          component={Login}
          options={{ header: null }}
        />
        <Stack.Screen name="Home" component={Home} />
      </Stack.Navigator>
    </NavigationNativeContainer>
  );
};

const style = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  inputContainer: {
    width: "80%",
    marginBottom: 20,
  },
  input: {
    borderStyle: "solid",
    borderWidth: 1,
  },
  label: {
    fontWeight: "bold",
    paddingVertical: 10,
  },
});

export default App;

<Stack.Navigator /> and <Stack.Screen /> The new declarative way to implement navigation in React Native.

if (loading) {
  return (
    <View style={style.container}>
      <ActivityIndicator size="large" />
    </View>
  );
}

Above code is a loading screen. In the mean while, getting the token from AsyncStorage.

Has error due to missing of Login and Home component ? Now, we will resolve the error. Add the Login and Home screen component respectively.

// In App.js too
import AsyncStorage from "@react-native-community/async-storage";

type Props = {
  navigation: NavigationProp,
};
function Login(props: Props) {
  return (
    <View style={style.container}>
      <View style={style.inputContainer}>
        <Text style={style.label}>Username</Text>
        <TextInput placeholder="Username" style={style.input} />
      </View>

      <View style={style.inputContainer}>
        <Text style={style.label}>Password</Text>
        <TextInput placeholder="******" secureTextEntry style={style.input} />
      </View>
      <Button
        title="Login"
        onPress={async () => {
          const { navigation } = props;

          // testing purpose
          await AsyncStorage.setItem("token", "yourtoken");
          navigation.navigate("Home");
        }}
      />
    </View>
  );
}

function Home() {
  return (
    <View style={style.container}>
      <Text>Home Page</Text>
    </View>
  );
}

Install AsyncStorage from react-native-community/async-storage.

Then, some modification to App component as below.

// App.js

const App: () => $ReactNode = () => {
  // code
  
  useEffect(() => {
    async function init() {
      setLoading(true);
      const userToken = await AsyncStorage.getItem("token");

      if (userToken) {
        setToken(userToken);
      }

      setLoading(false);
    }

    init();
  }, []);

  // return
  return (
    // Code
  )
}

Using the React Hooks – useEffect(). As initialize step, to fetch the token from AsyncStorage.

If the token exists or valid, depend on architecture. Then, we can decide the initialRouteName, either to Home or Login.

<Stack.Navigator initialRouteName={token ? "Home" : "Login"}>

Thanks for reading.  😁

Here is the full gists.

Comments

(0 Comments)

Your email address will not be published. Required fields are marked *