Fermer

novembre 13, 2019

Premiers pas avec la bibliothèque de navigation native React –


L'un des aspects les plus importants du développement d'applications React Native est la navigation. C’est ce qui permet aux utilisateurs d’accéder aux pages qu’ils recherchent. C'est pourquoi il est important de choisir la meilleure bibliothèque de navigation qui répond à vos besoins.

Si votre application comporte de nombreux écrans avec une interface utilisateur relativement complexe, il pourrait être intéressant d'explorer Réagissez Native Navigation au lieu de Navigation de réaction . En effet, React Navigation générera toujours des goulots d'étranglement en termes de performances, car il fonctionne sur le même thread JavaScript que le reste de l'application. Plus votre interface utilisateur est complexe, plus vous devez transmettre de données à ce pont, ce qui peut potentiellement le ralentir.

Dans ce didacticiel, nous examinerons la bibliothèque de navigation Native React de Wix, une bibliothèque de navigation alternative pour ceux qui recherchent des performances de navigation plus douces pour leurs applications React Native.

Vous voulez apprendre React Native à partir de la base? Cet article est un extrait de notre bibliothèque Premium. Obtenez une collection complète de livres natifs de React couvrant les bases, les projets, les astuces, les outils et plus avec SitePoint Premium. Inscrivez-vous maintenant pour seulement 9 $ par mois .

Prérequis

La connaissance de React et de React Native est requise pour suivre ce didacticiel. Une expérience préalable avec une bibliothèque de navigation telle que React Navigation est facultative.

Présentation de l’application

Afin de vous montrer comment utiliser la bibliothèque, nous allons créer une application simple qui l’utilise. L’application aura cinq écrans au total:

  • Initialisation : elle sert d’écran initial pour l’application. Si l'utilisateur est connecté, il va automatiquement accéder à l'écran d'accueil. Si ce n'est pas le cas, l'utilisateur accédera à l'écran de connexion.
  • Login : ceci permet à l'utilisateur de se connecter afin de pouvoir afficher la maison, la galerie et le flux. Pour simplifier les choses, on se moquera de l'identifiant; aucun code d'authentification réel ne sera impliqué. À partir de cet écran, l'utilisateur peut également accéder à l'écran Mot de passe oublié.
  • ForgotPassword : un écran de remplissage qui demande l'adresse électronique de l'utilisateur. Ceci servira simplement à démontrer la navigation dans les piles.
  • Home : l’écran initial que l’utilisateur verra lorsqu’il se connectera. Ils peuvent également accéder à la galerie ou aux écrans d’alimentation via un onglet de navigation inférieur. .
  • Galerie : un écran de remplissage illustrant une interface utilisateur de galerie de photos.
  • Feed : un écran de remplissage affichant une interface utilisateur de flux de nouvelles.

Voici à quoi ressemblera l'application: [19659003]  Réagissez Native Navigation demo gif

Vous pouvez trouver le code source de l'exemple d'application sur ce GitHub repo .

Amorcer l'application avec le modèle

Commençons par générer un Nouveau projet React Native:

 RNNavigation - version réactive natif init-@ative-0.57.8

Remarque: nous utilisons une version légèrement plus ancienne de React Native, car React Native Navigation ne fonctionne pas bien avec les versions ultérieures de React Native. React Native Navigation n’a pas vraiment suivi les modifications apportées au cœur de React Native depuis la version 0.58. La seule version connue pour fonctionner parfaitement avec React Native est la version que nous allons utiliser. Si vous cochez les numéros dans leur rapport vous verrez différents numéros dans la version 0.58 et 0.59 . Il existe peut-être des solutions de contournement sur ces deux versions, mais le pari le plus sûr reste la version 0.57.

En ce qui concerne la version 0.60 de React Native l'équipe principale a fait beaucoup . des changements . L'un d'eux est la migration vers AndroidX qui vise à préciser les packages fournis avec le système d'exploitation Android. Cela signifie essentiellement que si un module natif utilise l'un des anciens packages qui ont été migrés vers la nouvelle hiérarchie de paquets androidx. & Ast; le processus sera rompu. Il existe des outils tels que le jetifier qui permet la migration vers AndroidX. Mais cela ne garantit pas que React Native Navigation fonctionnera.

Ensuite, installez les dépendances de l'application:

  • react-native-navigation – la bibliothèque de navigation que nous allons utiliser.
  • @ react-native-community / async-storage – Pour enregistrer des données dans la mémoire de stockage locale de l'application.
  • Réactiver les icônes vectorielles natives – pour afficher les icônes de navigation dans l'onglet inférieur. 19659027] fil ajouter réact-natif-navigation @ réact-natif-communauté / stockage async réactif-natif-vecteur-icônes

    Dans les sections suivantes, nous allons configurer les packages que nous venons d’installer.

    Configuration de React Native Navigation

    Nous allons d’abord configurer la bibliothèque React Native Navigation. Les instructions que nous allons couvrir ici figurent également dans la documentation officielle . Malheureusement, il n’est pas écrit de manière très conviviale pour les débutants, nous allons donc en parler plus en détail.

    Remarque: le projet de démonstration comprend un Android et un iOS également. Vous pouvez vous en servir comme référence si vous rencontrez des problèmes lors de la configuration.

    Le nom de la bibliothèque étant très long, je l'appellerai simplement RNN à partir de maintenant.

    Android Configuration

    Dans cette section, nous verrons comment configurer RNN pour Android. Avant de poursuivre, il est important de mettre à jour tous les packages du SDK avec les dernières versions. Vous pouvez le faire via le gestionnaire de SDK Android.

    settings.gradle

    Ajoutez ce qui suit à votre fichier android / settings.gradle :

     include ': react-native-navigation'
    project (': react-native-navigation'). projectDir = nouveau fichier (rootProject.projectDir, '../node_modules/react-native-navigation/lib/android/app/')
    

    Gradle Wrapper Properties

    Dans votre android / gradle / wrapper / gradle-wrapper.properties mettez à jour la distribution de Gradle si elle ne l’utilise pas déjà: [19659037] distributionUrl = https : //services.gradle.org/distributions/gradle-4.4-all.zip

    build.gradle

    Ensuite, dans votre fichier android / build.gradle ajoutez mavenLocal () et mavenCentral () sous . buildscript -> référentiels :

     buildscript {
        référentiels {
          Google()
          jcenter ()
    
          // ajoute ces derniers:
          mavenLocal ()
          mavenCentral ()
        }
    }
    

    Ensuite, mettez à jour le chemin de classe sous le buildscript -> pour indiquer la version de Gradle dont nous avons besoin:

     buildscript {
      référentiels {
        ...
      }
    
      dépendances {
        chemin de classe 'com.android.tools.build:gradle:3.0.1'
      }
    
    }
    

    Sous tous les projets -> référentiels ajoutez mavenCentral () et JitPack. Cela nous permet d’extraire les données de le référentiel JitPack de Réactivité de Native Navigation :

     allprojects {
    tous les projets {
    
      référentiels {
        mavenLocal ()
        Google()
        jcenter ()
        mavenCentral () // ajouter ceci
        maven {url 'https://jitpack.io'} // ajouter ceci
      }
    
    }
    

    Ajoutez ensuite la configuration globale permettant de définir les outils de génération et les versions du SDK pour Android:

     allprojects {
      ...
    }
    
    ext {
        buildToolsVersion = "27.0.3"
        minSdkVersion = 19
        compileSdkVersion = 26
        targetSdkVersion = 26
        supportLibVersion = "26.1.0"
    }
    

    Enfin, nous souhaitons toujours conserver la commande par défaut react-native run-android lors de la compilation de l'application. Nous devons donc configurer Gradle pour qu'il ignore les autres versions de React Native Navigation, à l'exception de celle que nous utilisons. sont actuellement en utilisant ( de réactionNative57_5 ). En les ignorant, nous ne compilons que la version spécifique sur laquelle nous comptons:

     ext {
     ...
    }
    
    sous-projets {sous-projets ->
        afterEvaluate {
            if ((subproject.plugins.hasPlugin ('android') || | subproject.plugins.hasPlugin ('android-library')))) {
                Android {
                    variantFilter {variante ->
                        def noms = variant.flavors * .name
                        if (names.contains ("reactNative51") || names.contains ("reactNative55") || names.contains ("reactNative56") || names.contains ("reactNative57")) {
                            setIgnore (true)
                        }
                    }
                }
            }
        }
    }
    

    Remarque: il existe actuellement quatre autres types de RNN. Ce sont ceux que nous ignorons ci-dessus:

    • reactNative51
    • reactNative55
    • reactNative56
    • reactNative57

    android / app / build.gradle

    Sur votre android / app / build. fichier gradle sous android -> compileOptions assurez-vous que la version compatible de la source et est 1.8 :

     android {
      defaultConfig {
        ...
      }
    
      compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
      }
    }
    

    Ensuite, dans vos dépendances incluez react-native-navigation en tant que dépendance:

     dépendances {
        implementation fileTree (dir: "libs", inclure: ["*.jar"])
        implémentation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
        implementation "com.facebook.react: react-native: +"
        projet d'implémentation (': react-native-navigation') // add this
    }
    

    Enfin, sous android -> defaultConfig définissez le missingDimensionStrategy sur réagitativeNative57_5 . Il s’agit de la version de RNN compatible avec React Native 0.57.8:

     defaultConfig {
      applicationId "com.rnnavigation"
      minSdkVersion rootProject.ext.minSdkVersion
      targetSdkVersion rootProject.ext.targetSdkVersion
      missingDimensionStrategy "RNN.reactNativeVersion", "reactNative57_5" // ajoute ceci
      versionCode 1
      versionName "1.0"
      ndk {
        abiFilters "armeabi-v7a", "x86"
      }
    }
    

    MainActivity.java

    Sur votre fichier app / src / main / java / com / rnnavigation / MainActivity.java prolongez-vous du package NavigationActivity au lieu de:

     com.rnnavigation;
    
    // import com.facebook.react.ReactActivity;
    import com.reactnativenavigation.NavigationActivity;
    
    // Classe publique MainActivity prolongé ReactActivity {
    Classe publique MainActivity étend NavigationActivity {
      // supprime tout le code à l'intérieur
    }
    

    Puisque nous avons supprimé le code par défaut utilisé par React Native, il n'est plus nécessaire d'enregistrer le composant principal, comme vous le verrez plus loin dans la section Création de l'application :

     / / index.js
    importer {AppRegistry} de "react-native";
    importer l'application depuis "./App";
    importer {nom comme appName} depuis "./app.json";
    
    AppRegistry.registerComponent (appName, () => App);
    

    MainApplication.java

    Ensuite, vous devez également mettre à jour le fichier app / src / main / java / com / rnnavigation / MainApplication.java pour hériter de la classe de RNN. Commencez par importer les classes de RNN:

     import com.facebook.react.shell.MainReactPackage;
    import com.facebook.soloader.SoLoader;
    
    // ajoute ces
    import com.reactnativenavigation.NavigationApplication;
    import com.reactnativenavigation.react.NavigationReactNativeHost;
    import com.reactnativenavigation.react.ReactGateway;
    

    Ensuite, héritez de la classe NavigationApplication de RNN à la place:

     // la classe publique MainApplication extended Application implémente ReactApplication {
    Classe publique MainApplication étend NavigationApplication {
    
    }
    

    Enfin, remplacez complètement le contenu de la classe par le suivant:

     @Override
    protégé ReactGateway createReactGateway () {
      ReactNativeHost host = new NavigationReactNativeHost (this, isDebug (), createAdditionalReactPackages ()) {
        @Passer outre
        protected String getJSMainModuleName () {
          retourne "index";
        }
      };
      renvoyer new ReactGateway (this, isDebug (), hôte);
    }
    
    @Passer outre
    public boolean isDebug () {
      return BuildConfig.DEBUG;
    }
    
    Liste protégée  getPackages () {
      retour Tableaux.  asList (
    
      )
    }
    
    @Passer outre
    liste publique  createAdditionalReactPackages () {
      retourne getPackages ();
    }
    

    La seule chose qui vous semble familière dans le code ci-dessus est la méthode getPackages () . Comme dans le projet React Native standard, c’est ici que vous pouvez initialiser les classes de vos dépendances natives.

    Configuration iOS

    Dans cette section, nous allons configurer RNN pour iOS. Avant de poursuivre, il est important que vous ayez mis à jour Xcode avec la dernière version disponible. Cela permet d'éviter les erreurs potentielles liées aux modules Xcode obsolètes.

    Ouvrez tout d'abord le fichier ios / RNNavigation.xcodeproj avec Xcode. Ceci est le projet Xcode correspondant pour l'application.

    Une fois ouvert, dans le navigateur de projet (volet de gauche contenant les fichiers du projet), cliquez avec le bouton droit de la souris sur Bibliothèques -> Ajouter des fichiers à RNNavigation . Sur le sélecteur de fichier qui apparaît, accédez au répertoire node_modules / react-native-navigation / lib / ios et sélectionnez le ReactNativeNavigation.xcodeproj :

     add Projet rnn to xcode

    Cliquez ensuite sur RNNavigation dans la rangée TARGETS et cliquez sur l'onglet Build Phases . À partir de là, cherchez Lien binaire avec bibliothèques développez-le, puis cliquez sur le bouton permettant d'ajouter un nouvel élément:

     Le lien binaire avec les bibliothèques

    Sur le modal fenêtre qui apparaît, recherchez le fichier libReactNativeNavigation.a sélectionnez-le, puis cliquez sur le bouton Ajouter :

     recherchez rnn lib [19659003] Ouvrez ensuite le fichier AppDelegate.m et remplacez son contenu par le suivant. C’est fondamentalement le point d’entrée de l’application React Native (similaire au MainApplication.java sur Android). Nous le mettons à jour pour qu'il utilise RNN à la place:

     #import "AppDelegate.h"
    
     #import 
     #import 
     #import 
    
     @implementation AppDelegate
    
     - Application (BOOL): application (UIApplication *) application didFinishLaunchingWithOptions: (NSDictionary *) launchOptions
     {
         NSURL * jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot: @ "index" fallbackResource: nil];
         [ReactNativeNavigation bootstrap:jsCodeLocation launchOptions:launchOptions];
    
         retourner OUI;
     }
    
     @fin
    

    C’est à peu près tout pour la liaison de RNN à iOS. Toutefois, si vous rencontrez des problèmes, vous devrez probablement suivre également la section suivante.

    Problèmes courants

    Dans cette section, nous allons passer en revue certains des problèmes les plus courants que vous pouvez rencontrer lors de la création d'un lien entre RNN sur iOS.

    Lorsque vous avez modifié et enregistré le fichier AppDelegate.m vous rencontrez probablement ce problème. Cela apparaîtra en lignes ondulées rouges dans le fichier lui-même:

    ! Fichier 'RCTBundleURLProvider.h' introuvable
    

    Cela se produit car le schéma React est manquant dans votre projet.

    Pour le rendre disponible, exécutez les commandes suivantes dans le répertoire racine de votre projet ( RNNavigation ): [19659020] npm installer -g react-native-git-upgrade
    réagir-native-git-upgrade

    Ceci ajoutera les fichiers manquants à votre projet.

    Une fois que cela est fait, accédez à Produit -> Scheme -> Gestion des schémas puis cliquez sur le bouton + pour ajouter un nouveau schéma. Dans le menu déroulant Cible sélectionnez Réagissez puis cliquez sur OK pour l'ajouter:

    puis cliquez sur puis cliquez sur . assurez-vous que les cases Show et Shared sont cochées:

     réagit aux cases à cocher

    Le prochain problème que vous pourriez rencontrer est le suivant:

     Fichier 'ReactNativeNavigation / ReactNativeNavigation.h' introuvable.
    

    Cela signifie qu’il n’a pas pu trouver ledit fichier dans le chemin de votre projet. Pour le résoudre, cliquez sur RNNavigation dans les TARGETS . Cliquez ensuite sur Paramètres de construction et, en dessous, assurez-vous que All et combiné est utilisé comme filtre, puis recherchez en-tête . dans la barre de recherche. Double-cliquez sur En-tête des chemins de recherche cliquez sur le bouton + et ajoutez $ (SRCROOT) /../ node_modules / react-native-navigation / lib / ios. comme chemin:

     ajouter des chemins de recherche

    Configuration des icônes AsyncStorage et vectorielles

    Le processus de configuration des icônes AsyncStorage et vectorielles est très similaire aux processus d'installation décrits ci-dessus. Il suffit de vous relier à la documentation officielle.

    Voici les instructions pour AsyncStorage:

    • Configuration Android .
    • iOS Configuration . Assurez-vous de suivre la version non-pods, car il est plus facile de le configurer. Les non-pods (abréviation de non CocoaPods) n’utilisent pas CocoaPods en tant que gestionnaire de dépendance. Le fichier principal du module natif sera simplement lié en tant que bibliothèque. C’est essentiellement la même chose que nous avons faite avec le fichier libReactNativeNavigation.a précédemment.

    Et voici les instructions pour Vector Icons. Pour simplifier les choses, il suffit de suivre les instructions pour ajouter tout le dossier Polices au projet Xcode:

    Remarque: vous pouvez toujours consulter le GitHub repo en cas de perte. [19659003] OK, cela a donc nécessité beaucoup de configuration manuelle. Si vous avez vraiment besoin de RNN dans votre projet, c’est une nécessité. Chaque fois que vous introduisez une nouvelle dépendance ayant un lien natif, vous devez suivre les instructions pour la lier manuellement. Le lien react-native ne fonctionnera pas, car nous avons remplacé ReactApplication par NavigationApplication dans MainApplication.java . Le lien est ainsi créé. maintenant fait un peu différemment. Vous pouvez probablement vous en tirer en utilisant le lien réactif-natif si vous savez exactement ce que vous faites et que vous pouvez complètement annuler ce qui a été fait. Mais il est plus sûr de simplement suivre les instructions de liaison du manuel.

    Création de l'application

    Nous sommes maintenant prêts à commencer à créer l'application.

    index.js

    Tout d'abord, ouvrez l'index existant . .js à la racine du répertoire du projet et remplacez son contenu par le suivant. Cela sert de point d'entrée de l'application. Si vous avez remarqué, il n’est plus nécessaire d’enregistrer le composant principal de l’application à l’aide de AppRegistry de React Native. Au lieu de cela, nous utilisons maintenant la méthode registerComponent () de RNN . Cela concerne les mises à jour précédemment apportées aux fichiers MainActivity.java et AppDelegate.m .

    La méthode registerComponent () accepte les méthodes de l'écran. nom unique et composant à utiliser pour le rendu de l'écran. Une fois l’appareil enregistré, nous appelons la méthode registerAppLaunchedListener () pour définir l’écran racine de l’application sur LoadingScreen . Ceci est similaire à ce que fait AppRegistry.registerComponent () :

     // index.js
    importer {Navigation} de "react-native-navigation";
    importer l'icône de "react-native-vector-icons / FontAwesome";
    
    importer Chargement depuis "./src/screens/Loading"; // l'écran de chargement
    
    importer "./loadIcons"; // fichier pour le chargement des icônes à utiliser dans la navigation par onglet inférieur
    
    Navigation.registerComponent (`LoadingScreen`, () => Chargement);
    
    Navigation.events (). RegisterAppLaunchedListener (() => {
      // définit le composant racine
      Navigation.setRoot ({
        racine: {
          composant: {
            nom: "LoadingScreen"
          }
        }
      });
    });
    

    Écran de chargement

    L'écran de chargement sert de point d'entrée de l'application. Mais vous demandez peut-être pourquoi un écran de chargement? Pourquoi pas un écran de connexion à la place? En effet, notre exemple d'application dispose d'un système de connexion fictif, ce qui signifie que nous devons d'abord déterminer si un utilisateur est déjà connecté ou non. Utiliser un écran de chargement fonctionne mieux que de devoir d'abord charger un écran de connexion pour découvrir qu'un utilisateur est déjà connecté; nous devons donc les naviguer jusqu'à l'écran d'accueil.

    Commencez par créer un src /. screens / Loading.js et ajoutez ce qui suit:

     // src / screens / Loading.js
    importer Réagir, {Composant} de "réagir";
    importer {View, Text, ActivityIndicator, StyleSheet} de "react-native";
    
    importer {goToLogin, goToTabs} de "../../navigation"; // importer les fonctions de chargement de l'écran de connexion ou de l'écran des onglets (montre l'écran d'accueil par défaut)
    
    importer AsyncStorage à partir de "@ react-native-community / async-storage";
    

    Créez ensuite le composant lui-même. Lorsque le composant est monté, nous essayons d'obtenir le nom d'utilisateur de l'utilisateur connecté à partir du stockage local. Si tel est le cas, l'utilisateur est dirigé vers les onglets, sinon vers l'écran de connexion:

     export default class Loading chargement de Component {
      async composantDidMount () {
        const username = wait AsyncStorage.getItem ("nom d'utilisateur");
        si (nom d'utilisateur) {
          goToTabs (global.icons, nom d'utilisateur);
        } autre {
          goToLogin ();
        }
      }
    
      render () {
        // affiche l'indicateur de chargement
        revenir (
          
            
          
        );
      }
    }
    //
    
    const styles = StyleSheet.create ({
      récipient: {
        flex: 1,
        justifierContent: "center",
        alignItems: "center"
      }
    });
    

    Dans le code ci-dessus, notez que nous passons dans les global.icons en tant qu’argument de la fonction de goToTabs () . Cette valeur est définie dans le fichier loadIcons.js que nous avons importé du fichier index.js . Son travail consiste à charger les icônes à utiliser pour les onglets du bas, comme vous le verrez plus tard.

    Nous enregistrons ici tous les écrans de l'application et déclarons nos fonctions de navigation pour naviguer entre l'écran de connexion et les écrans à onglets:

     // navigation.js
    importer {Navigation} de "react-native-navigation";
    
    importer le login depuis "./src/screens/Login";
    importer ForgotPassword de "./src/screens/ForgotPassword";
    importer Home de "./src/screens/Home";
    importer un flux depuis "./src/screens/Feed";
    importer une galerie de "./src/screens/Gallery";
    
    Navigation.registerComponent (`LoginScreen`, () => Connexion);
    Navigation.registerComponent (`ForgotPasswordScreen`, () => ForgotPassword);
    Navigation.registerComponent (`HomeScreen`, () => Accueil);
    Navigation.registerComponent (`FeedScreen`, () => Flux);
    Navigation.registerComponent (`GalleryScreen`, () => Galerie);
    

    La fonction goToLogin () crée une navigation dans la pile. Dans RNN, ces types de navigation sont appelés «Layouts». Actuellement, il n'y en a que trois: les piles, les onglets et les tiroirs. Nous n’utiliserons que la pile et les onglets dans ce didacticiel, mais voici un bref aperçu de chacun d’entre eux:

    • Stack : chaque nouvel écran auquel vous accédez est placé au-dessus de l’écran actuel. Ainsi, lorsque vous revenez à l'écran précédent, vous devez simplement extraire l'écran actuel de la pile. Nous allons utiliser la navigation dans les piles pour naviguer entre l’écran de connexion et l’écran de mot de passe oublié.
    • Onglet : chaque écran est accessible via un onglet de navigation inférieur. Chaque onglet comporte à la fois une icône et un texte décrivant l'écran vers lequel l'utilisateur navigue. Ce type de navigation est couramment utilisé s'il existe deux écrans principaux ou plus dans l'application. Avoir un onglet de navigation permet un accès facile entre ces écrans. Nous utiliserons l'onglet de navigation pour naviguer entre les écrans d'accueil, de galerie et de flux.
    • Tiroir : également appelé menu latéral. Ceci s'appelle tiroir car il est généralement caché dans une icône de hamburger et ne montre que le menu en-dessous quand on clique dessus.

    Pour revenir au code, nous avons ajouté l'écran de connexion comme un enfant de la navigation dans la pile, même si l'écran ForgotPassword en fait également partie. Comme mentionné précédemment, nous allons utiliser la navigation par pile pour naviguer entre l’écran de connexion et l’écran de mot de passe oublié. Pourtant, nous n’avons ajouté ici que l’écran de connexion en tant qu’enfant. L'ajouter fera simplement l'écran par défaut de la pile. Dans une navigation de pile, vous ne devriez ajouter que l'écran initial de cette pile spécifique en tant qu'enfant, comme vous le verrez plus tard.

    L'exigence minimale pour un enfant est d'ajouter la propriété name pour chaque objet. écran. C'est le nom de l'écran à utiliser pour le rendu. Ce nom doit être identique à celui que vous avez utilisé lors de l’enregistrement du composant:

     export const goToLogin = () =>
      Navigation.setRoot ({
        racine: {
          pile: {
            // crée une pile de navigation
            id: "stackMain",
            enfants: [
              {
                component: {
                  name: "LoginScreen"
                }
              }
            ]
          }
        }
      });
    

    Remarque: il n'est pas obligatoire de fournir un ID pour la navigation, mais c'est une bonne pratique - surtout si vous savez que vous commencerez à utiliser le même type de présentation plusieurs fois dans votre application.

    Ensuite, ajoutez la fonction goToTabs () . Contrairement à la fonction précédente, elle accepte deux arguments: icons et nom d'utilisateur . icons est le tableau d'icônes à utiliser pour les onglets individuels, tandis que username est le nom d'utilisateur de l'utilisateur qui s'est connecté. Cette fois, nous utilisons les bottomTabs navigation. Comme son nom l'indique, cela permet à l'utilisateur de naviguer entre les écrans à l'aide des onglets du bas. Vous pouvez créer des onglets inférieurs en utilisant le format suivant :

     const iconColor = "# 444";
    const selectedIconColor = "# 0089da";
    
    export const goToTabs = (icones, nom d'utilisateur) => {
      Navigation.setRoot ({
        racine: {
          bottomTabs: {
            // crée une navigation par les onglets inférieurs
    
            id: "bottomTabsMain",
            enfants: [
              {
                component: {
                  name: "HomeScreen",
                  options: {
                    bottomTab: {
                      fontSize: 11,
                      text: "Home",
                      icon: icons[0]
                      iconColor,
                      selectedIconColor
                    }
                  },
    
                  // passe le nom d'utilisateur comme accessoire de navigation à l'écran d'accueil
                  passProps: {
                    Nom d'utilisateur
                  }
                }
              },
    
              {
                composant: {
                  nom: "GalleryScreen",
                  Les options: {
                    bottomTab: {
                      fontSize: 11,
                      texte: "Galerie",
                      icône: icônes [1],
                      iconColor,
                      selectedIconColor
                    }
                  }
                }
              },
    
              {
                composant: {
                  nom: "FeedScreen",
                  Les options: {
                    bottomTab: {
                      fontSize: 11,
                      text: "Feed",
                      icône: icônes [2],
                      iconColor,
                      selectedIconColor
                    }
                  }
                }
              }
            ]
          }
        }
      });
    };
    

    Comme vous l’avez vu dans le code ci-dessus, cela utilise à peu près le même format que celui utilisé pour la navigation dans les piles. La seule différence est que, cette fois, nous spécifions également une propriété options pour l'individu bottomTab . Ces options sont principalement utilisées pour configurer les styles de chaque onglet. Elles s’expliquent d'elles-mêmes, alors je n'entrerai pas dans les détails, mais je veux simplement expliquer la propriété de l'icône . Par défaut, cela accepte une image locale requise par un appel require ('./ path / to / image.png') . Mais comme nous avons déjà installé Vector Icons, nous pourrions aussi bien l’utiliser comme source d’icônes. Le seul problème est que nous ne pouvons pas vraiment fournir un composant React comme valeur pour l’icône car il attend une ressource. Le paramètre icons accepte un tableau de ressources d’icône, c’est ce que nous utilisons à la place. Vous apprendrez comment nous les chargeons dans la section suivante.

    Remarque: vous pouvez trouver davantage d’options de style pour les onglets du bas dans la documentation officielle de Styling . Il suffit de chercher bottomTabs ou bottomTab .

    loadIcons.js

    Voici le code du fichier loadIcons que nous avons importé dans l'index . .js plus tôt. Ceci utilise les icônes de FontAwesome . Nous utilisons ici la méthode getImageSource () de Vector Icons pour obtenir la ressource image réelle. Cela nous permet de l'utiliser comme icône pour les onglets du bas:

     // loadIcons.js
    importer l'icône de "react-native-vector-icons / FontAwesome";
    
    (une fonction() {
      Promise.all ([
        Icon.getImageSource("home", 11), // name of icon, size
        Icon.getImageSource("image", 11),
        Icon.getImageSource("rss-square", 11)
      ]). Then (valeurs asynchrones => {
        global.icons = valeurs; // le rend disponible globalement pour que nous n'ayons pas besoin de le charger à nouveau
      });
    }) ();
    

    Écran de connexion

     écran de connexion

    L'écran de connexion est l'écran par défaut que l'utilisateur verra s'il n'est pas connecté. À partir de là, il peut se connecter en entrant son nom d'utilisateur. ou ils peuvent cliquer sur de mot de passe oublié pour afficher l'écran de réinitialisation de leur mot de passe. Comme mentionné précédemment, tout cela est simulé et aucun code d'authentification réel n'est utilisé:

     // src / screens / Login.js
    importer Réagir, {Composant} de "réagir";
    importer {Navigation} de "react-native-navigation";
    importer {
      Vue,
      Texte,
      Saisie de texte,
      Bouton,
      TouchableOpacity,
      Feuille de style
    } de "react-native";
    importer AsyncStorage à partir de "@ react-native-community / async-storage";
    
    importer {goToTabs} de "../../navigation";
    
    export default class Login extension du composant {
      static get options () {
        revenir {
          barre du haut: {
            visible: false // besoin de définir ceci car les écrans d'une navigation de pile ont un en-tête par défaut
          }
        };
      }
    
      state = {
        Nom d'utilisateur: ""
      };
    
      render () {
        revenir (
          
            
              
                
                   Entrez votre nom d'utilisateur 
                    this.setState ({username})}
                    style = {styles.textInput}
                  />
                
    
                

    Voici le code de connexion. Ceci stocke simplement le nom d'utilisateur dans la mémoire de stockage locale et permet aux utilisateurs d'accéder aux écrans à onglets:

     login = async () => {
      const {nom d'utilisateur} = this.state;
      si (nom d'utilisateur) {
        wait AsyncStorage.setItem ("nom d'utilisateur", nom d'utilisateur);
        goToTabs (global.icons, nom d'utilisateur);
      }
    };
    

    Enfin, voici le code pour naviguer vers un autre écran via la navigation par pile. Appelez simplement la méthode Navigation.push () et transmettez l’ID de l’écran actuel en premier argument et l’écran sur lequel vous souhaitez naviguer en tant que second. Le nom doit être identique à celui que vous avez utilisé lorsque vous avez appelé Navigation.registerComponent () dans le fichier navigation.js :

     goToForgotPassword = () => {
      Navigation.push (this.props.componentId, {
        composant: {
          nom: "ForgotPasswordScreen"
        }
      });
    };
    

    Écran ForgotPassword Screen

     Écran de mot de passe oublié

    Comme indiqué précédemment, cet écran est simplement utilisé comme élément de remplissage pour illustrer la navigation dans les piles. Assurez-vous que le topBar est réglé sur visible car c’est là que se trouve le bouton de retour permettant de revenir à l’écran de connexion:

     // src / screens / ForgotPassword.js
    importer Réagir, {Composant} de "réagir";
    importer {View, Text, TextInput, Button, StyleSheet} de "react-native";
    
    La classe d'exportation par défaut ForgotPassword étend Component {
      static get options () {
        revenir {
          barre du haut: {
            visible: true, // visible
            Titre: {
              text: "Mot de passe oublié"
            }
          }
        };
      }
    
      state = {
        email: ""
      };
    
      render () {
        revenir (
          
            
              
                
                  Enter your email
                   this.setState({ email })}
                    style={styles.textInput}
                  />
                
    
                

    You can also have a separate button for going back to the previous screen. All you have to do is call the Navigation.pop() method:

    Navigation.pop(this.props.componentId);
    

    Home Screen

    home screen

    The Home screen is the default screen for the tabbed navigation, so it’s what the user will see by default when they log in. This screen shows the user’s name that was passed as a navigation prop as well as a button for logging out. Clicking the logout button will simply delete the username from local storage and navigate the user back to the login screen:

    // src/screens/Home.js
    import React, { Component } from "react";
    import { View, Text, Button, StyleSheet } from "react-native";
    import Icon from "react-native-vector-icons/FontAwesome";
    import AsyncStorage from "@react-native-community/async-storage";
    
    import { goToLogin } from "../../navigation";
    
    export default class Home extends Component {
      render() {
        const { username } = this.props;
        return (
          
            Hi {username}!
            

    In case you’re wondering how we got access to the usernamewe’ve passed it as a navigation prop from the navigation file earlier:

    // navigation.js
    {
      component: {
        name: "HomeScreen",
        options: {
          ...
        },
    
        // here:
        passProps: {
          username
        },
    
      }
    },
    

    gallery screen

    The Gallery screen is just a filler screen so we won’t be delving too much into it. Basically, it just shows a photo gallery UI:

    // src/screens/Gallery.js
    import React, { Component } from "react";
    import {
      View,
      Text,
      FlatList,
      Image,
      Dimensions,
      StyleSheet
    } from "react-native";
    
    const { width } = Dimensions.get("window");
    const base_width = width / 2;
    
    const images = [
      {
        id: 1,
        src: require("../images/blake-richard-verdoorn-20063-unsplash.jpg")
      },
      {
        id: 2,
        src: require("../images/casey-horner-487085-unsplash.jpg")
      },
      {
        id: 3,
        src: require("../images/sacha-styles-XK7thML3zEQ-unsplash.jpg")
      },
      {
        id: 4,
        src: require("../images/eberhard-grossgasteiger-1036384-unsplash.jpg")
      },
      {
        id: 5,
        src: require("../images/justin-kauffman-449060-unsplash.jpg")
      },
      {
        id: 6,
        src: require("../images/vincent-guth-182001-unsplash.jpg")
      }
    ];
    
    export default class Gallery extends Component {
      render() {
        return (
          
             item.id.toString()}
              numColumns={2}
              renderItem={this.renderImage}
            />
          
        );
      }
      //
    
      renderImage = ({ item }) => {
        return (
          
        );
      };
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1
      }
    });
    

    Feed Screen

    feed screen

    Just like the Gallery screen, the Feed screen is also a filler. It simply shows a news feed UI:

    // src/screens/Feed.js
    import React, { Component } from "react";
    import {
      View,
      Text,
      FlatList,
      Image,
      TouchableOpacity,
      StyleSheet
    } from "react-native";
    
    const news_items = [
      {
        id: 1,
        title: "The HTML Handbook",
        summary:
          "HTML is the foundation of the marvel called the Web. Discover all you need to know about it in this handy handbook!",
        image: require("../images/amanda-phung-1281331-unsplash.jpg")
      },
      {
        id: 2,
        title: "Angular RxJs In-Depth",
        summary:
          "In this tutorial, we'll learn to use the RxJS 6 library with Angular 6 or Angular 7...",
        image: require("../images/daniil-silantev-318853-unsplash.jpg")
      },
      {
        id: 3,
        title: "How to Create Code Profiles in VS Code",
        summary:
          "This post piggybacks off of the work done by @avanslaars who is a fellow instructor at egghead.io....",
        image: require("../images/vincent-van-zalinge-38358-unsplash.jpg")
      }
    ];
    
    export default class Feed extends Component {
      render() {
        return (
          
             item.id.toString()}
              renderItem={this.renderItem}
            />
          
        );
      }
      //
    
      renderItem = ({ item }) => {
        return (
          
            
              
                
                  {item.title}
                  {item.summary}
                
              
              
                
              
            
          
        );
      };
      //
    
      goToNews = () => {};
    }
    //
    
    const styles = StyleSheet.create({
      container: {
        flex: 1
      },
      news_item: {
        flex: 1,
        flexDirection: "row",
        paddingRight: 20,
        paddingLeft: 20,
        paddingTop: 20,
        paddingBottom: 20,
        borderBottomWidth: 1,
        borderBottomColor: "#E4E4E4"
      },
      news_text: {
        flex: 2,
        flexDirection: "row",
        padding: 15
      },
      title: {
        fontSize: 28,
        fontWeight: "bold",
        color: "#000",
        fontFamily: "georgia"
      },
      news_photo: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center"
      },
      photo: {
        width: 120,
        height: 120
      }
    });
    

    Running the App

    At this point, you should be able to run the app:

    react-native run-android
    react-native run-ios
    

    Try out the app and see if it performs better than React Navigation (if you’ve used it before).

    Conclusion and Next Steps

    In this tutorial, you learned how to use the React Native Navigation library. Specifically, you learned how to set up React Native Navigation and use the stack and tab navigation. You also learned how to load icons from React Native Vector Icons instead of using image icons.

    As a next step, you might want to check out how animations can be customized, how to implement a side menu navigationor view the examples of different layout types.

    If you’re still unsure about which navigation library to use for your next project, be sure to check out this post: React Navigation vs. React Native Navigation: Which is right for you?

    You can find the source code of the sample app on this GitHub repo.




Source link