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]
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 distributionde 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
ajoutezmavenLocal ()
etmavenCentral ()
sous. buildscript
->référentiels
:buildscript { référentiels { Google() jcenter () // ajoute ces derniers: mavenLocal () mavenCentral () } }
Ensuite, mettez à jour le
chemin de classe
sous lebuildscript
->buildscript { référentiels { ... } dépendances { chemin de classe 'com.android.tools.build:gradle:3.0.1' } }
Sous
tous les projets
->référentiels
ajoutezmavenCentral ()
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
sousandroid
->compileOptions
assurez-vous que la version compatible de la source1.8
:android { defaultConfig { ... } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
Ensuite, dans vos
dépendances
incluezreact-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 lemissingDimensionStrategy
surré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 packageNavigationActivity
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 leReactNativeNavigation.xcodeproj
: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:
Sur le modal fenêtre qui apparaît, recherchez le fichier
libReactNativeNavigation.a
sélectionnez-le, puis cliquez sur le bouton Ajouter : [19659003] Ouvrez ensuite le fichierAppDelegate.m
et remplacez son contenu par le suivant. C’est fondamentalement le point d’entrée de l’application React Native (similaire auMainApplication.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:
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: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
parNavigationApplication
dansMainApplication.java
. Le lien est ainsi créé. maintenant fait un peu différemment. Vous pouvez probablement vous en tirer en utilisantle 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
etAppDelegate.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éthoderegisterAppLaunchedListener ()
pour définir l’écran racine de l’application surLoadingScreen
. Ceci est similaire à ce que faitAppRegistry.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 fonctionde goToTabs ()
. Cette valeur est définie dans le fichierloadIcons.js
que nous avons importé du fichierindex.js
. Son travail consiste à charger les icônes à utiliser pour les onglets du bas, comme vous le verrez plus tard.navigation.js
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
etnom d'utilisateur
.icons
est le tableau d'icônes à utiliser pour les onglets individuels, tandis queusername
est le nom d'utilisateur de l'utilisateur qui s'est connecté. Cette fois, nous utilisons lesbottomTabs
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'individubottomTab
. 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ônerequire ('./ 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ôneicons
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
oubottomTab
.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éthodegetImageSource ()
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
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 ( ); } // suivant: ajout du code de connexion } // const styles = StyleSheet.create ({ wrapper: { flex: 1 }, récipient: { flex: 1, alignItems: "center", justifierContent: "center", rembourrage: 20 }, fieldContainer: { marginTop: 20 }, étiquette: { taille de la police: 16 }, saisie de texte: { hauteur: 40 marginTop: 5, marginBottom: 10, borderColor: "#ccc", borderWidth: 1, backgroundColor: "#eaeaea", rembourrage: 5 } });
Voici le code de connexion. Ceci stocke simplement le nom d'utilisateur
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 nomNavigation.registerComponent ()
dans le fichiernavigation.js
:goToForgotPassword = () => { Navigation.push (this.props.componentId, { composant: { nom: "ForgotPasswordScreen" } }); };
Écran ForgotPassword Screen
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é survisible
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 ( ); } // sendEmail = async () => {}; } // const styles = StyleSheet.create({ wrapper: { flex: 1 }, container: { flex: 1, alignItems: "center", justifyContent: "center", padding: 20 }, fieldContainer: { marginTop: 20 }, label: { fontSize: 16 }, textInput: { height: 40, marginTop: 5, marginBottom: 10, borderColor: "#ccc", borderWidth: 1, backgroundColor: "#eaeaea", padding: 5 } });
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
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 ( ); } // logout = async () => { await AsyncStorage.removeItem("username"); goToLogin(); }; } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: "center", alignItems: "center" }, text: { fontSize: 18, fontWeight: "bold" } });
In case you’re wondering how we got access to the
username
we’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 ( ); } // renderImage = ({ item }) => { return ( ); }; } const styles = StyleSheet.create({ container: { flex: 1 } });
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 ( ); } // renderItem = ({ item }) => { return ( ); }; // 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