Fermer

août 11, 2021

Gérer le montage et le démontage des itinéraires de navigation dans React Native


Résumé rapide ↬

Souvent, vous avez besoin de deux ensembles différents de piles de navigation pour l'authentification avant et après l'utilisateur. Habituellement, pour voir plus de contenu, vous devez être authentifié d'une manière ou d'une autre. Voyons comment monter et démonter la pile de navigation en fonction d'une condition satisfaite dans React Native.

Dans cet article, nous allons parcourir le montage et démontage des routes de navigation dans React Native. Un comportement attendu de votre application est qu'une fois la condition d'authentification remplie, un nouvel ensemble d'itinéraires de navigation est disponible uniquement pour les utilisateurs connectés, tandis que les autres écrans qui étaient affichés avant l'authentification sont supprimés et ne peuvent être renvoyés que si le l'utilisateur se déconnecte de l'application.

Pour la sécurité de votre application, les itinéraires protégés vous permettent d'afficher uniquement certaines informations/contenus de votre application à des utilisateurs spécifiques, tout en limitant l'accès aux personnes non autorisées.

Nous serons travailler avec Expo pour ce projet car cela nous aidera à nous concentrer sur le problème au lieu de nous soucier de beaucoup de configurations. Les mêmes étapes exactes dans cet article peuvent être suivies pour une application React Native nue.

Vous devez être familiarisé avec JavaScript et React Native pour suivre ce didacticiel. Voici quelques éléments importants que vous devriez déjà connaître :

Configuration du projet et authentification de base

Si vous débutez avec expo et que vous ne savez pas comment installer expo, consultez la documentation officielle. Une fois l'installation terminée, allez-y pour initialiser un nouveau projet React Native avec expo à partir de notre invite de commande :

expo init navigation-project

Vous serez présenté avec quelques options pour choisir comment vous voulez que la configuration de base soit :

Configuration de base du projet React Native

( Grand aperçu)

Dans notre cas, sélectionnons la première option pour configurer notre projet en tant que document vierge. Maintenant, attendez que l'installation des dépendances JavaScript soit terminée.

Une fois notre application configurée, nous pouvons changer notre répertoire vers notre nouveau répertoire de projet et l'ouvrir dans votre éditeur de code préféré. Nous devons installer la bibliothèque que nous utiliserons pour AsyncStorage et nos bibliothèques de navigation. Dans le répertoire de votre dossier dans votre terminal, collez la commande ci-dessus et choisissez un modèle (blank fonctionnerait) pour installer nos dépendances de projet.

Regardons à quoi sert chacune de ces dépendances :

  • @react-native-community/async-storage
    Comme localStorage sur le Web, il s'agit d'une API React Native permettant de conserver les données sur un appareil dans des paires clé-valeur.
  • @react-native. -community/masked-view, react-native-screens, react-native-gesture-handle
    Ces dépendances sont des utilitaires de base utilisés par la plupart des navigateurs pour créer la structure de navigation dans l'application. (En savoir plus dans Démarrer avec la navigation React Native.)
  • @react-navigation/native
    Ceci est la dépendance de la navigation React Native.
  • @react -navigation/stack
    Il s'agit de la dépendance pour la navigation dans la pile dans React Native.
npm install @react-native-community/async-storage @react-native-community/masked-view @react-navigation/native @ react-navigation/stack react-native-screens react-native-gesture-handle

Pour démarrer l'application, utilisez expo start à partir du répertoire de l'application de votre terminal. Une fois l'application démarrée, vous pouvez utiliser l'application expo depuis votre téléphone mobile pour scanner le code à barres et afficher l'application, ou si vous avez un émulateur Android/simulateur IOS, vous pouvez ouvrir l'application via l'outil de développement expo qui s'ouvre dans votre navigateur lorsque vous démarrez une application expo. Pour les exemples d'images de cet article, nous utiliserons Genymotions pour voir notre résultat. Voici à quoi ressemblera notre résultat final dans Genymotions :

résultat final dans Genymotions

(Large preview)

Structures de dossiers

Créons notre structure de dossiers dès le départ afin qu'il nous soit plus facile de l'utiliser au fur et à mesure :

Nous avons d'abord besoin de deux dossiers :

  • context
    Ce dossier contiendra le contexte de toute notre application car nous travaillerons avec l'API Context pour la gestion globale de l'état.
  • views
    Ce dossier contiendra à la fois le dossier de navigation et les vues pour différents écrans.[19659042]Allez-y et créez les deux dossiers dans votre répertoire de projet.

    Dans le dossier de contexte, créez un dossier appelé authContext et créez deux fichiers à l'intérieur du dossier authContext :[19659006]AuthContext.js,

  • AuthState.js.

Nous aurons besoin de ces fichiers lorsque nous commencerons à travailler avec l'API Context.

Allez maintenant à views dossier que nous avons créé et créons deux autres dossiers à l'intérieur, à savoir :

Maintenant, nous avons n'êtes pas encore terminé, dans le dossier screenscréez ces deux autres dossiers :

  • postAuthScreens,
  • preAuthScreens.

Si vous avez suivi la configuration du dossier correctement, voici à quoi devrait ressembler votre structure de dossier pour le moment :

structure de dossier

( Grand aperçu)
Plus après le saut ! Continuez à lire ci-dessous ↓

Création de notre premier écran

Créons maintenant notre premier écran et appelons-le welcomeScreen.js à l'intérieur du Dossier preAuthScreens.

preAuthScreens > welcomeScreen.js

Voici le contenu de notre fichier welcomeScreen.js :

import React from ' ';
import { View, Text, Button, StyleSheet, TextInput } depuis 'react-native';

const Écran d'accueil = () => {

  const onUserAuthentication = () => {
    console.log("Bouton d'authentification utilisateur cliqué")
  }

  revenir (
    
      Bienvenue sur notre application !
      
        
        

Voici ce que nous avons fait dans le bloc de code ci-dessus :

Tout d'abord, nous avons importé les éléments dont nous avons besoin de la bibliothèque React Native, à savoir, ViewTextBoutonSaisie de texte. Ensuite, nous avons créé notre composant fonctionnel WelcomeScreen.

Vous remarquerez que nous avons importé le StyleSheet de React Native et l'avons utilisé pour définir des styles pour notre en-tête ainsi que notre [19659066].

Enfin, nous exportons le composant WelcomeScreen en bas du code.

Maintenant que nous avons terminé, faisons fonctionner ce composant comme prévu en utilisant le hook useState pour stocker les valeurs des entrées et mettre à jour leurs états chaque fois qu'un changement se produit dans les champs d'entrée. Nous allons également importer le hook useCallback de React car nous en aurons besoin plus tard pour contenir une fonction.

Tout d'abord, alors que nous sommes toujours dans le composant WelcomeScreennous avons besoin pour importer le useState et useCallback depuis React.

import React, { useState, useCallback } depuis 'react' ;

Maintenant dans le WelcomeScreen composant fonctionnel, créons respectivement les deux états de l'email et du mot de passe :

...
const Écran d'accueil = () => {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  revenir (
    ...
  )
}
...

Ensuite, nous devons modifier nos champs afin qu'ils obtiennent leur valeur à partir de leurs états respectifs et mettent à jour leur état lorsque la valeur de l'entrée est mise à jour :

import React, { useState, useCallback } de 'réagir';
import { View, Text, Button, StyleSheet, TextInput } depuis 'react-native';

const Écran d'accueil = () => {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')

  const onInputChange = (valeur, setState) => {
    setState(valeur);
  }
  revenir (
    
      ...
      
         onInputChange(value, setEmail)}
        />
         onInputChange(valeur, setPassword)}
        />
        ...
      
    
  )
}
...

Dans le code ci-dessus, voici ce que nous avons fait :

  • Nous avons fait la valeur de chacune des entrées de texte pour pointer vers leurs états respectifs.
  • Nous avons ajouté le onChangeText à nos entrées de texte. Cela se déclenche à chaque fois qu'une nouvelle valeur est saisie ou supprimée des champs de saisie.
  • Nous avons appelé notre fonction onInputChange qui accepte deux arguments :
    • La valeur actuelle est fournie par le gestionnaire onChangeText.
    • Le setter de l'état qui doit être mis à jour (pour le premier champ de saisie nous passons setEmail et le second nous passons setPassword.
    • Enfin, nous écrivons notre fonction onInputChangeet notre fonction ne fait qu'une chose : elle met à jour les états respectifs avec la nouvelle valeur.

La prochaine chose sur laquelle nous devons travailler est la fonction onUserAuthentication() qui est appelée chaque fois que le bouton de soumission du formulaire est cliqué.

Idéalement, l'utilisateur doit déjà avoir créé un compte et une connexion impliqueront une certaine logique backend pour vérifier que l'utilisateur existe, puis attribuer un jeton à l'utilisateur. Dans notre cas, puisque nous n'utilisons aucun backend, nous allons créer un objet contenant les informations de connexion utilisateur correctes, puis authentifier un utilisateur uniquement lorsque les valeurs qu'il saisit correspondent à nos valeurs fixes de l'objet de connexion de email et mot de passe que nous allons créer.

Voici le code dont nous avons besoin pour le faire :

...

const correctAuthenticationDetails = {
  email : 'demouser@gmail.com',
  mot de passe : 'mot de passe'
}
const Écran d'accueil = () => {
  ...

  // Cette fonction est appelée lorsque le bouton `AUTHENTICATE` est cliqué
  const onUserAuthentication = () => {
    si (
      email !== correctAuthenticationDetails.email ||
      mot de passe !== correctAuthenticationDetails.password
    ) {
      alert('L'email ou le mot de passe est incorrect')
      revenir
    }
      // Ici, nous allons gérer ce qui se passe si les informations de connexion sont // correctes
  }

  ...
  revenir (
    ...
  )
}
...

L'une des premières choses que vous remarquerez dans le code ci-dessus est que nous avons défini un correctAuthenticationDetails (qui est un objet qui contient les informations de connexion correctes que nous attendons d'un utilisateur) en dehors du Composant fonctionnel WelcomeScreen().

Ensuite, nous avons écrit le contenu de la fonction onUserAuthentication() et utilisé une instruction conditionnelle pour vérifier si le email ou le mot de passe détenu dans les états respectifs ne correspond pas à celui que nous avons fourni dans notre objet.

Si vous souhaitez voir ce que nous avons fait jusqu'à présent, importez le composant WelcomeScreen dans votre App.js comme ceci :

Ouvrez le fichier App.js et remplacez le code entier par ceci :

import { StatusBar } de 'expo-status- bar';
importer React à partir de « react » ;
importer { View } depuis 'react-native' ;
importer WelcomeScreen depuis './views/screens/preAuthScreens/welcomeScreen' ;
exporter la fonction par défaut App() {
  revenir (
    
      
      
    
  );
}

En regardant attentivement le code ci-dessus, vous verrez que nous avons importé le composant WelcomeScreenpuis l'avons utilisé dans la fonction App().

Voici à quoi ressemble le résultat de notre WelcomeScreen :

le résultat de WelcomeScreen

(Large preview)

Maintenant que nous avons fini de créer le composant WelcomeScreenallons de l'avant et commençons à travailler avec l'API de contexte pour gérer notre état global.

Pourquoi l'API de contexte ?

En utilisant l'API de contexte, nous le faisons. pas besoin d'installer de bibliothèque supplémentaire dans ReactJS, sa configuration est moins stressante et constitue l'un des moyens les plus populaires de gérer l'état global dans ReactJS. Pour une gestion d'état légère, c'est un bon choix.

Création de notre contexte

Si vous vous en souvenez, nous avons précédemment créé un dossier context et créé un sous-dossier à l'intérieur appelé authContext.

Allons maintenant au fichier AuthContext.js dans le dossier authContext et créons notre contexte :

context > authContext > AuthContext.js


import React, { createContext } de 'react';
const AuthContext = createContext();
exporter AuthContext par défaut ;

Le AuthContext que nous venons de créer contient la valeur d'état loading et les valeurs d'état userToken. Actuellement, dans le createContext que nous avons déclaré dans le bloc de code ci-dessus, nous n'avons initialisé aucune valeur par défaut ici, donc notre contexte est actuellement undefined. Un exemple de valeur du contexte d'authentification pourrait être {loading : false, userToken : 'abcd}

Le fichier AuthState.js contient notre logique d'API de contexte et leurs valeurs d'état. Les fonctions écrites ici peuvent être appelées de n'importe où dans notre application et lorsqu'elles mettent à jour les valeurs dans l'état, elles sont également mises à jour globalement.

Tout d'abord, introduisons toutes les importations dont nous aurons besoin dans ce fichier :

context > AuthContext > AuthState.js

import React, { useState } de 'react';
importer AuthContext de './AuthContext' ;
importer AsyncStorage de '@react-native-community/async-storage';

Nous avons importé le hook useState() de ReactJS pour conserver nos états, nous avons importé le fichier AuthContext nous avons créé ci-dessus car c'est là que notre contexte vide pour l'authentification est initialisé et nous devrons l'utiliser comme vous le verrez plus tard pendant que nous progressons, enfin nous importons le package AsyncStorage (similaire à localStorage pour le web).

AsyncStorage est une API React Native qui vous permet de conserver les données hors ligne sur l'appareil dans une application React Native.

...

const AuthState = (props) => {
    const [userToken, setUserToken] = useState(null);
    const [isLoading, setIsLoading] = useState(true);

    const onAuthentication = async() => {
        const USER_TOKEN = "drix1123q2"
        wait AsyncStorage.setItem('user-token', USER_TOKEN);
        setUserToken(USER_TOKEN);
        console.warn("l'utilisateur a été authentifié !")
    }

    revenir (
        
            {accessoires.enfants}
        
    )
}
exporter l'état d'authentification par défaut ;

Dans le bloc de code ci-dessus, voici ce que nous avons fait :

  • Nous avons déclaré deux états pour userToken et isLoading. L'état userToken sera utilisé pour stocker le jeton enregistré dans AsyncStoragetandis que l'état isLoading sera utilisé pour suivre l'état de chargement (initialement il est défini sur vrai). Nous en saurons plus sur l'utilisation de ces deux états au fur et à mesure.

  • Ensuite, nous avons écrit notre fonction onAuthentication(). Cette fonction est une fonction async qui est appelée lorsque vous cliquez sur le bouton de connexion à partir du fichier welcomeScreen.jsx. Cette fonction ne sera appelée que si l'e-mail et le mot de passe fournis par l'utilisateur correspondent à l'objet de détail utilisateur correct que nous avons fourni. Habituellement, ce qui se passe lors de l'authentification est qu'un jeton est généré pour l'utilisateur après que l'utilisateur soit authentifié sur le backend à l'aide d'un package tel que JWTet ce jeton est envoyé au frontend. Puisque nous n'allons pas dans tout cela pour ce tutoriel, nous avons créé un jeton statique et l'avons conservé dans une variable appelée USER_TOKEN.

  • Ensuite, nous utilisons le mot-clé await pour définissez notre jeton utilisateur sur AsyncStorage avec le nom user-token. L'instruction console.warn() est juste utilisée pour vérifier que tout s'est bien passé, vous pouvez l'enlever quand vous le souhaitez.

  • Enfin, nous passons notre fonction onAuthenticated en tant que fonction value à l'intérieur de notre afin que nous puissions accéder et appeler la fonction de n'importe où dans notre application.

screens > preAuth > welcomeScreen.js

Tout d'abord, importez useContext depuis ReactJS et importez le AuthContext depuis le fichier AuthContext.js.

import React, { useState, useContext } depuis 'react' ;
importer AuthContext de '../../../context/authContext/AuthContext'
...

Maintenant, à l'intérieur du composant fonctionnel welcomeScreen()utilisons le contexte que nous avons créé :

...
const Écran d'accueil = () => {
  const { onAuthentication } = useContext (AuthContext)
  const onUserAuthentication = () => {
    si (
      email !== correctAuthenticationDetails.email ||
      mot de passe !== correctAuthenticationDetails.password
    ) {
      alert('L'email ou le mot de passe est incorrect')
      revenir
    }
    surAuthentification()
  }
  revenir (
    ...
  )
}
...

Dans le bloc de code ci-dessus, nous avons déstructuré la fonction onAuthentication de notre AuthContextpuis nous l'avons appelée dans notre fonction onUserAuthentication() et supprimé le console.log() qui était là avant maintenant.

À l'heure actuelle, cela générera une erreur car nous n'avons pas encore accès au AuthContext. Pour utiliser le AuthContext n'importe où dans votre application, nous devons envelopper le fichier de niveau supérieur dans notre application avec le AuthState (dans notre cas, il s'agit du App.js ).

Accédez au fichier App.js et remplacez le code par celui-ci :

import React from 'react' ;
importer WelcomeScreen depuis './views/screens/preAuthScreens/welcomeScreen' ;
importer AuthState de './context/authContext/AuthState'

exporter la fonction par défaut App() {
  revenir (
    
      
    
  );
}

Nous avons fait du chemin et nous en avons terminé avec cette section. Avant de passer à la section suivante où nous configurons notre routage, créons un nouvel écran. L'écran que nous sommes sur le point de créer sera le fichier HomeScreen.js qui est censé s'afficher uniquement après une authentification réussie.

Allez à : screens > postAuth.

Créez un nouveau fichier appelé HomeScreen.js. Voici le code du fichier HomeScreen.js :

screens > postAuth > HomeScreen.js

import React from 'react' ;
importer { Vue, Texte, Bouton, Feuille de style } à partir de 'react-native' ;

const Écran d'accueil = () => {

  const onLogout = () => {
    console.warn("Bouton de déconnexion cliqué")
  }

  revenir (
    
      Vous êtes maintenant authentifié ! Bienvenue !
      

Pour l'instant, le bouton de déconnexion a une instruction factice console.log(). Plus tard, nous créerons la fonctionnalité de déconnexion et la transmettrons à l'écran à partir de notre contexte.

Configuration de nos itinéraires

Nous devons créer trois (3) fichiers dans notre dossier de navigation :

  • postAuthNavigator .js,
  • preAuthNavigator.js,
  • AppNavigator.js.

Une fois que vous avez créé ces trois fichiers, accédez au preAuthNaviagtor.js que vous venez de créer et écrivez ceci :

navigation > preAuthNavigator.js

import React from "react" ;
importer { createStackNavigator } depuis "@react-navigation/stack" ;
importer WelcomeScreen depuis "../screens/preAuthScreens/welcomeScreen" ;

const PreAuthNavigator = () => {
    const { Navigateur, Écran } = createStackNavigator();

    revenir (
        
            
        
    )
}
exporter PreAuthNavigator par défaut ;

Dans le fichier ci-dessus, voici ce que nous avons fait :

  • Nous avons importé le createStackNavigator à partir du @react-navigation/stack que nous utilisons pour notre navigation dans la pile. Le createStackNavigatorFournit à votre application un moyen de passer d'un écran à l'autre, chaque nouvel écran étant placé au-dessus d'une pile. Par défaut, le navigateur de pile est configuré pour avoir l'apparence familière d'iOS et d'Android : les nouveaux écrans glissent par la droite sur iOS, disparaissent par le bas sur Android. Cliquez ici si vous souhaitez en savoir plus sur le navigateur de pile dans React Native.
  • Nous avons déstructuré Navigator et Screen à partir du createStackNavigator().
  • Dans notre instruction return, nous avons créé notre navigation avec le et créé notre écran avec le . cela signifie que si nous avions plusieurs écrans accessibles avant l'authentification, nous aurons ici plusieurs balises qui les représentent.
  • Enfin, nous exportons notre composant PreAuthNavigator.

Laissons-nous faire. une chose similaire pour le fichier postAuthNavigator.js.

navigation > postAuthNavigator.js

import React from "react" ;
importer { createStackNavigator } depuis "@react-navigation/stack" ;
importer HomeScreen depuis "../screens/postAuthScreens/HomeScreen" ;
const PostAuthNavigator = () => {
  const { Navigateur, Écran} = createStackNavigator();
  revenir (
    
      
     
  )
}
exporter PostAuthNavigator par défaut ;

Comme nous le voyons dans le code ci-dessus, la seule différence entre preAuthNavigator.js et postAuthNavigator.js est l'écran rendu. Alors que le premier prend le WelcomeScreenle postAuthNavigator.js prend le HomeScreen.

Pour créer notre AppNavigator.js nous besoin de créer quelques éléments.

Étant donné que AppNavigator.js est l'endroit où nous allons basculer et vérifier quel itinéraire sera disponible pour l'accès par l'utilisateur, nous avons besoin de plusieurs écrans en place pour que cela fonctionne correctement, décrivons d'abord les éléments que nous devons créer :

  1. TransitionScreen.js
    Pendant que l'application décide quelle navigation elle va monter, nous voulons qu'un écran de transition apparaisse. En règle générale, l'écran de transition sera une flèche de chargement ou toute autre animation personnalisée choisie pour l'application, mais dans notre cas, nous utiliserons une balise de base pour afficher loading….
  2. checkAuthenticationStatus()
    Cette fonction est ce que nous appellerons pour vérifier l'état d'authentification qui déterminera quelle pile de navigation va être montée. Nous allons créer cette fonction dans notre contexte et l'utiliser dans le fichier Appnavigator.js.

Maintenant, créons notre fichier TransitionScreen.js.

. ]screens > TransitionScreen.js

import React de 'react' ;
importer { Text, View } de 'react-native' ;

const TransitionScreen = () => {
  revenir (
    
      Chargement...
    
  )
}

exporter l'écran de transition par défaut

Notre écran de transition n'est qu'un simple écran qui affiche le texte de chargement. Nous verrons où l'utiliser au fur et à mesure que nous procédons dans cet article.

Ensuite, allons dans notre AuthState.js et écrivons notre checkAuthenticationStatus() :

context > authContext > AuthState.js

import React, { useState, useEffect } à partir de 'react' ;
importer AuthContext de './AuthContext' ;
importer AsyncStorage depuis '@react-native-community/async-storage' ;

const AuthState = (props) => {
    const [userToken, setUserToken] = useState(null);
    const [isLoading, setIsLoading] = useState(true);

    ...
    useEffect(() => {
        checkStatusAuthentification()
    }, [])
    
    const checkAuthenticationStatus = async () => {
        essayer {
            const returnToken = wait AsyncStorage.getItem('user-toke n');
            setUserToken(returnedToken);
            console.warn('Jeton utilisateur défini sur la valeur d'état)
        } catch(err){
            console.warn(`Voici l'erreur qui s'est produite lors de la récupération du jeton : ${err}`)
        }
        setIsLoading(false)
    }


    const onAuthentication = async() => {
        ...
    }

    revenir (
        
            {accessoires.enfants}
        
    )
}
exporter l'état d'authentification par défaut ;

Dans le bloc de code ci-dessus, nous avons écrit la fonction checkAuthenticationStatus(). Dans notre fonction, voici ce que nous faisons :

  • Nous avons utilisé le mot-clé await pour obtenir notre jeton à partir de AsyncStorage. Avec AsyncStoragesi aucun jeton n'est fourni, il renvoie null. Notre état initial userToken est également défini sur null.
  • Nous utilisons setUserToken pour définir notre valeur renvoyée à partir de AsyncStorage comme notre nouveau userToken. Si la valeur renvoyée est nullcela signifie que notre userToken reste null.
  • Après le try{}…catch(){}nous définissons isLoading sur false car la fonction de vérification de l'état d'authentification est terminée. Nous aurons besoin de la valeur de isLoading pour savoir si nous devrions toujours afficher le TransitionScreen ou non. Cela vaut la peine d'envisager de définir une erreur s'il y a une erreur lors de la récupération du jeton afin que nous puissions montrer à l'utilisateur un bouton « Réessayer » ou « Réessayer » lorsque l'erreur est rencontrée.
  • Chaque fois que AuthState monte, nous voulez vérifier l'état d'authentification, nous utilisons donc le crochet useEffect() ReactJS pour le faire. Nous appelons notre fonction checkAuthenticationStatus() à l'intérieur du hook useEffect() et définissons la valeur de isLoading sur false lorsque c'est fait.
  • Enfin, nous ajoutons nos états à nos valeurs afin que nous puissions y accéder de n'importe où dans notre application couverte par l'API Context.

Maintenant que nous avons notre fonction, il est temps de revenir à notre AppNavigator.js et écrivez le code pour monter un navigateur de pile particulier en fonction du statut d'authentification :

navigation > AppNavigator.js

Tout d'abord, nous allons importer tout ce dont nous avons besoin pour notre AppNavigator.js.

import React, { useEffect, useContext } de "react" ;
importer PreAuthNavigator depuis "./preAuthNavigator" ;
importer PostAuthNavigator depuis "./postAuthNavigator" ;
importer { NavigationContainer } de "@react-navigation/native"
importer { createStackNavigator } depuis "@react-navigation/stack" ;
importer AuthContext de "../../context/authContext/AuthContext" ;
importer TransitionScreen depuis "../screens/TransitionScreen" ;

Maintenant que nous avons toutes nos importations, créons la fonction AppNavigator().

...
const AppNavigator = () => {

}

exporter AppNavigator par défaut

Ensuite, nous allons maintenant écrire le contenu de notre fonction AppNavigator() :

import React, { useState, useEffect, useContext } from "react" ;
importer PreAuthNavigator depuis "./preAuthNavigator" ;
importer PostAuthNavigator depuis "./postAuthNavigator" ;
importer { NavigationContainer } de "@react-navigation/native"
importer { createStackNavigator } depuis "@react-navigation/stack" ;
importer AuthContext de "../../context/authContext/AuthContext" ;
importer TransitionScreen depuis "../screens/transition" ;

const AppNavigator = () => {
    const { Navigateur, Écran } = createStackNavigator();
    const authContext = useContext(AuthContext);
    const { userToken, isLoading } = authContext;
    if(isLoading) {
      retour 
    }
    revenir (
    
      
        {
          userToken == null ? (
             nul }}
            />
          ) : (
             nul }}
            />
          )
        }
      
    
  )
}

exporter AppNavigator par défaut

Dans le bloc de code ci-dessus, voici un aperçu de ce que nous avons fait :

  • Nous avons créé un navigateur de pile et déstructuré le Navigator et l'Screen à partir de celui-ci.
  • Nous avons importé le userToken et le isLoading de notre AuthContext
  • Lorsque le AuthState est monté, le checkAuthenticationStatus() y est appelé dans le hook useEffecct. Nous utilisons l'instruction if pour vérifier si isLoading est truesi c'est true l'écran que nous retournons est notre qui nous avons créé plus tôt car la fonction checkAuthenticationStatus() n'est pas encore terminée.
  • Une fois notre checkAuthenticationStatus() terminé, isLoading est défini sur false et nous retournons nos principaux composants de navigation.
  • Le NavigationContainer a été importé du @react-navigation/native. Il n'est utilisé qu'une seule fois dans le navigateur principal de niveau supérieur. Notez que nous n'utilisons pas ceci dans le preAuthNavigator.js ou le postAuthNavigator.js.
  • Dans notre AppNavigator()nous créons toujours une pile navigateur. Si le userToken obtenu de notre API de contexte est nullnous montons le PreAuthNavigatorsi sa valeur est autre (ce qui signifie que le AsyncStorage.getItem () dans checkAuthenticationStatus() a renvoyé une valeur réelle), puis nous montons le PostAuthNavigator. Our conditional rendering is done using the ternary operator.

Now we’ve set up our AppNavigator.js. Next, we need to pass our AppNavigator into our App.js file.

Let’s pass our AppNavigator into the App.js file:

App.js

 ...
import AppNavigator from './views/navigation/AppNavigator';

...
return (
    
      
    
  );

Let’s now see what our app looks like at the moment:

Here’s what happens when you supply an incorrect credential while trying to log in:

Adding The Logout Functionality

At this point, our authentication and route selection process is complete. The only thing left for our app is to add the logout functionality.

The logout button is in the HomeScreen.js file. We passed an onLogout() function to the onPress attribute of the button. For now, we have a simple console.log() statement in our function, but in a little while that will change.

Now, let’s go to our AuthState.js and write the function for logout. This function simply clears the AsyncStorage where the user token is saved.

context > authContext > AuthState.js

...
const AuthState = (props) => {
    ...

    const userSignout = async() => {
        await AsyncStorage.removeItem('user-token');
        setUserToken(null);
    }


    return (
      ...
    )
}

export default AuthState;

The userSignout() is an asynchronous function that removes the user-token from our AsyncStorage.

Now we need to call the userSignout() function in our HomeScreen.js any time the logout button is clicked on.

Let’s go to our HomeScreen.js and use ther userSignout() from our AuthContext.

screens > postAuthScreens > HomeScreen.js

import React, { useContext } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import AuthContext from '../../../context/authContext/AuthContext'

const HomeScreen = () => {
  const { userSignout } = useContext(AuthContext)
  
  const onLogout = () => {
    userSignout()
  }
  return (
    
      Now you're authenticated! Welcome!
 

In the above code block we imported thee useContext hook from ReactJS, then we imported our AuthContext. Next, we destructured the userSignout function from our AuthContext and this userSignout() function is called in our onLogout() function.

Now whenever our logout button is clicked, the user token in our AsyncStorage is cleared.

Voila! our entire process is finished.

Here’s what happens when you press the back button after you’re logged in:

Pressing the back button after logging into the app.

Here’s what happens when you press the back button after logging out:

Pressing the back button after logging out of the app.

Here are some different behaviors we notice when using this pattern in our navigation stack switching:

  1. You’ll notice that there was nowhere we needed to make use of navigation.navigate() or navigation.push() to go to another route after login. Once our state is updated with the user token, the navigation stack rendered is automatically changed.
  2. Pressing the back button on your device after login is successful cannot take you back to the login page, instead, it closes the app entirely. This behavior is important because you don’t want the user to be able to return back to the login page except they log out of the app. The same thing applies to logging out — once the user logs out, they cannot use the back button to return to the HomeScreen screen, but instead, the app closes.

Conclusion

In many Apps, authentication is one of the most important parts because it confirms that the person trying to gain access to protected content has the right to access the information. Learning how to do it right is an important step in building a great, intuitive, and easy to use/navigate the application.

Building on top of this code, here are a few things you might consider adding:

Here are also some important resources I found that will enlighten you more about authentication, security and how to do it right:

Resources

Smashing Editorial" width="35" height="46" loading="lazy" decoding="async(ks, vf, yk, il)




Source link