Umgang mit dem Mounten und Unmounten von Navigationsrouten in React Native

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Oft benötigen Sie zwei verschiedene Sätze von Navigationsstacks für die Authentifizierung vor und nach dem Benutzer. Normalerweise müssen Sie sich irgendwie authentifizieren, um mehr Inhalte sehen zu können. Sehen wir uns an, wie Sie den Navigationsstapel basierend auf einer erfüllten Bedingung in React Native ein- und aushängen.

In diesem Artikel gehen wir durch das Mounten und Unmounten von Navigationsrouten in React Native. Ein erwartetes Verhalten Ihrer App ist, dass sobald die Authentifizierungsbedingung erfüllt ist, ein neuer Satz von Navigationsrouten nur für angemeldete Benutzer verfügbar ist, während die anderen Bildschirme, die vor der Authentifizierung angezeigt wurden, entfernt werden und nicht zu ihnen zurückkehren können, es sei denn Benutzer meldet sich von der Anwendung ab.

Für die Sicherheit in Ihrer App bieten Ihnen geschützte Routen die Möglichkeit, bestimmte Informationen/Inhalte in Ihrer App nur bestimmten Benutzern anzuzeigen und gleichzeitig den Zugriff für Unbefugte einzuschränken.

Wir werden für dieses Projekt mit Expo zusammenarbeiten, weil es uns hilft, uns auf das vorliegende Problem zu konzentrieren, anstatt uns um viele Einstellungen zu kümmern. Die exakt gleichen Schritte in diesem Artikel könnten für eine bloße React Native-Anwendung befolgt werden.

Sie müssen mit JavaScript und React Native vertraut sein, um dieses Tutorial durchzuarbeiten. Hier sind ein paar wichtige Dinge, mit denen Sie bereits vertraut sein sollten:

  • Benutzerdefinierte Komponenten in React Native (wie man Komponenten erstellt, Requisiten in einer Komponente empfängt, weitergibt und verwendet). Weiterlesen.
  • Reagieren Sie auf die Navigation. Weiterlesen.
  • Stack-Navigator in React Native. Weiterlesen.
  • Grundkenntnisse der React Native Core-Komponenten ( <View/> , <Text/> , etc.). Weiterlesen.
  • Reagieren AsyncStorage . Weiterlesen.
  • Kontext-API. Weiterlesen.

Projekteinrichtung und Basisauthentifizierung

Wenn Sie neu in der Verwendung von Expo sind und nicht wissen, wie Expo installiert wird, besuchen Sie die offizielle Dokumentation. Sobald die Installation abgeschlossen ist, initialisieren Sie ein neues React Native-Projekt mit Expo von unserer Eingabeaufforderung aus:

 expo init navigation-project

Ihnen werden einige Optionen angezeigt, mit denen Sie auswählen können, wie das Basis-Setup aussehen soll:

Reagieren Sie auf das Basis-Setup des Native-Projekts
(Große Vorschau)

Wählen wir in unserem Fall die erste Option, um unser Projekt als leeres Dokument einzurichten. Warten Sie nun, bis die Installation der JavaScript-Abhängigkeiten abgeschlossen ist.

Sobald unsere App eingerichtet ist, können wir unser Verzeichnis in unser neues Projektverzeichnis ändern und es in Ihrem bevorzugten Code-Editor öffnen. Wir müssen die Bibliothek installieren, die wir für AsyncStorage und unsere Navigationsbibliotheken verwenden werden. Fügen Sie in Ihrem Ordnerverzeichnis in Ihrem Terminal den obigen Befehl ein und wählen Sie eine Vorlage ( blank würde funktionieren), um unsere Projektabhängigkeiten zu installieren.

Schauen wir uns an, wofür jede dieser Abhängigkeiten ist:

  • @react-native-community/async-storage
    Wie localStorage im Web ist es eine React Native API, um Daten auf einem Gerät in Schlüssel-Wert-Paaren zu speichern.
  • @React-Native-Community/Masked-View, React-Native-Screens, React-Native-Gesture-Handle
    Diese Abhängigkeiten sind zentrale Dienstprogramme, die von den meisten Navigatoren verwendet werden, um die Navigationsstruktur in der App zu erstellen. (Lesen Sie mehr unter Erste Schritte mit der React Native-Navigation.)
  • @react-navigation/native
    Dies ist die Abhängigkeit für die React Native-Navigation.
  • @react-navigation/stack
    Dies ist die Abhängigkeit für die Stack-Navigation in 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

Um die Anwendung zu starten, verwenden Sie expo start aus dem App-Verzeichnis in Ihrem Terminal. Sobald die App gestartet ist, können Sie die Expo-App von Ihrem Mobiltelefon aus verwenden, um den Barcode zu scannen und die Anwendung anzuzeigen, oder wenn Sie einen Android-Emulator/IOS-Simulator haben, können Sie die App über das Expo-Entwicklertool öffnen öffnet sich in Ihrem Browser, wenn Sie eine Expo-Anwendung starten. Für die Bildbeispiele in diesem Artikel verwenden wir Genymotions, um unser Ergebnis zu sehen. So wird unser Endergebnis in Genymotions aussehen:

Endergebnis in Genymotions
(Große Vorschau)

Ordnerstrukturen

Lassen Sie uns unsere Ordnerstruktur von Anfang an erstellen, damit wir im weiteren Verlauf einfacher damit arbeiten können:

Wir brauchen zuerst zwei Ordner:

  • Kontext
    Dieser Ordner enthält den Kontext für unsere gesamte Anwendung, da wir mit der Kontext-API für die globale Zustandsverwaltung arbeiten werden.
  • Ansichten
    Dieser Ordner enthält sowohl den Navigationsordner als auch die Ansichten für verschiedene Bildschirme.

Fahren Sie fort und erstellen Sie die beiden Ordner in Ihrem Projektverzeichnis.

Erstellen Sie im Kontextordner einen Ordner mit dem Namen authContext und erstellen Sie zwei Dateien im Ordner authContext :

  • AuthContext.js ,
  • AuthState.js .

Wir benötigen diese Dateien, wenn wir anfangen, mit der Kontext-API zu arbeiten.

Gehen Sie nun zu dem von uns erstellten Ordner views und erstellen Sie darin zwei weitere Ordner, nämlich:

  • Navigation ,
  • Bildschirme .

Jetzt sind wir noch nicht fertig, erstellen Sie im Bildschirmordner diese beiden weiteren Ordner:

  • postAuthScreens ,
  • preAuthScreens .

Wenn Sie die Ordnereinrichtung korrekt durchgeführt haben, sollte Ihre Ordnerstruktur im Moment so aussehen:

Ordnerstruktur
(Große Vorschau)
Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Erstellen unseres ersten Bildschirms

Lassen Sie uns nun unseren ersten Bildschirm erstellen und ihn im Ordner „ preAuthScreens “ „ welcomeScreen.js “ nennen.

preAuthScreens > welcomeScreen.js

Hier ist der Inhalt unserer Datei welcomeScreen.js :

 import React from 'react'; import { View, Text, Button, StyleSheet, TextInput } from 'react-native'; const WelcomeScreen = () => { const onUserAuthentication = () => { console.log("User authentication button clicked") } return ( <View style={styles.container}> <Text style={styles.header}>Welcome to our App!</Text> <View> <TextInput style={styles.inputs} placeholder="Enter your email here.." /> <TextInput style={styles.inputs} secureTextEntry={true} placeholder="Enter your password here.." /> <Button title="AUTHENTICATE" onPress={onUserAuthentication} /> </View> </View> ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, header: { fontSize: 25, fontWeight: 'bold', marginBottom: 30 }, inputs: { width: 300, height: 40, marginBottom: 10, borderWidth: 1, } }) export default WelcomeScreen

Folgendes haben wir im obigen Codeblock getan:

Zuerst haben wir die Dinge, die wir brauchen, aus der React Native-Bibliothek importiert, nämlich View , Text , Button , TextInput . Als nächstes haben wir unsere funktionale Komponente WelcomeScreen .

Sie werden feststellen, dass wir das StyleSheet von React Native importiert und es verwendet haben, um Stile für unseren Header und auch unseren <TextInput /> zu definieren.

Zuletzt exportieren wir die WelcomeScreen Komponente am Ende des Codes.

Nachdem wir damit fertig sind, wollen wir diese Komponente dazu bringen, wie erwartet zu funktionieren, indem wir den useState Hook verwenden, um die Werte der Eingaben zu speichern und ihre Zustände jedes Mal zu aktualisieren, wenn eine Änderung in den Eingabefeldern auftritt. Wir werden auch den useCallback Hook von React importieren, da wir ihn später benötigen werden, um eine Funktion zu halten.

Zunächst müssen wir, während wir uns noch in der WelcomeScreen Komponente befinden, useState und useCallback von React importieren.

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

Lassen Sie uns nun in der Funktionskomponente WelcomeScreen die beiden Zustände für die E-Mail bzw. das Passwort erstellen:

 ... const WelcomeScreen = () => { const [email, setEmail] = useState('') const [password, setPassword] = useState('') return ( ... ) } ...

Als Nächstes müssen wir unsere <TextInput /> Felder so ändern, dass sie ihren Wert aus ihren jeweiligen Zuständen erhalten und ihren Zustand aktualisieren, wenn der Wert der Eingabe aktualisiert wird:

 import React, { useState, useCallback } from 'react'; import { View, Text, Button, StyleSheet, TextInput } from 'react-native'; const WelcomeScreen = () => { const [email, setEmail] = useState('') const [password, setPassword] = useState('') const onInputChange = (value, setState) => { setState(value); } return ( <View> ... <View> <TextInput style={styles.inputs} placeholder="Enter your email here.." value={email} onChangeText={(value) => onInputChange(value, setEmail)} /> <TextInput style={styles.inputs} secureTextEntry={true} placeholder="Enter your password here.." value={password} onChangeText={(value) => onInputChange(value, setPassword)} /> ... </View> </View> ) } ...

Im obigen Code haben wir Folgendes getan:

  • Wir haben den value jeder der Texteingaben so gemacht, dass sie auf ihre jeweiligen Zustände zeigen.
  • Wir haben den Handler onChangeText zu unseren Texteingaben hinzugefügt. Dies wird immer dann ausgelöst, wenn ein neuer Wert in die Eingabefelder eingegeben oder gelöscht wird.
  • Wir haben unsere onInputChange Funktion aufgerufen, die zwei Argumente akzeptiert:
    • Der aktuelle value wird vom onChangeText Handler bereitgestellt.
    • Der Setter des Zustands, der aktualisiert werden soll (für das erste Eingabefeld übergeben wir setEmail und für das zweite übergeben wir setPassword .
    • Schließlich schreiben wir unsere onInputChange Funktion, und unsere Funktion macht nur eines: Sie aktualisiert die jeweiligen Zustände mit dem neuen Wert.

Das nächste, woran wir arbeiten müssen, ist die Funktion onUserAuthentication() , die immer dann aufgerufen wird, wenn auf die Schaltfläche zum Senden des Formulars geklickt wird.

Im Idealfall muss der Benutzer bereits ein Konto erstellt haben, und die Anmeldung erfordert eine Art Backend-Logik, um zu überprüfen, ob der Benutzer existiert, und ihm dann ein Token zuzuweisen. Da wir in unserem Fall kein Backend verwenden, erstellen wir ein Objekt, das die korrekten Anmeldedaten des Benutzers enthält, und authentifizieren dann einen Benutzer nur, wenn die von ihm eingegebenen Werte mit unseren festen Werten aus dem von uns festgelegten Anmeldeobjekt von email und password übereinstimmen schaffen.

Hier ist der Code, den wir dafür brauchen:

 ... const correctAuthenticationDetails = { email: '[email protected]', password: 'password' } const WelcomeScreen = () => { ... // This function gets called when the `AUTHENTICATE` button is clicked const onUserAuthentication = () => { if ( email !== correctAuthenticationDetails.email || password !== correctAuthenticationDetails.password ) { alert('The email or password is incorrect') return } // In here, we will handle what happens if the login details are // correct } ... return ( ... ) } ...

Eines der ersten Dinge, die Sie im obigen Code bemerken werden, ist, dass wir ein correctAuthenticationDetails (ein Objekt, das die korrekten Anmeldedaten enthält, die wir von einem Benutzer erwarten) außerhalb der Funktionskomponente WelcomeScreen() .

Als nächstes haben wir den Inhalt der Funktion onUserAuthentication() und eine bedingte Anweisung verwendet, um zu prüfen, ob die email -Adresse oder das password in den jeweiligen Zuständen nicht mit denen übereinstimmen, die wir in unserem Objekt angegeben haben.

Wenn Sie sehen möchten, was wir bisher gemacht haben, importieren Sie die WelcomeScreen- Komponente wie folgt in Ihre App.js :

Öffnen Sie die App.js -Datei und ersetzen Sie den gesamten Code durch diesen:

 import { StatusBar } from 'expo-status-bar'; import React from 'react'; import { View } from 'react-native'; import WelcomeScreen from './views/screens/preAuthScreens/welcomeScreen'; export default function App() { return ( <View> <StatusBar /> <WelcomeScreen /> </View> ); }

Wenn Sie sich den Code oben genau ansehen, werden Sie sehen, dass wir die WelcomeScreen- Komponente importiert und dann in der App() Funktion verwendet haben.

So sieht das Ergebnis unseres WelcomeScreen aus:

das Ergebnis von WelcomeScreen
(Große Vorschau)

Nachdem wir nun die WelcomeScreen -Komponente erstellt haben, können wir weitermachen und mit der Kontext-API arbeiten, um unseren globalen Status zu verwalten.

Warum Kontext-API?

Durch die Verwendung der Kontext-API müssen wir keine zusätzliche Bibliothek in ReactJS installieren, die Einrichtung ist weniger stressig und eine der beliebtesten Methoden zum Umgang mit dem globalen Zustand in ReactJS. Für eine einfache Zustandsverwaltung ist dies eine gute Wahl.

Unseren Kontext schaffen

Wenn Sie sich erinnern, haben wir zuvor einen Kontextordner erstellt und darin einen Unterordner mit dem Namen authContext erstellt .

Navigieren wir nun zur Datei AuthContext.js im Ordner authContext und erstellen unseren Kontext:

Kontext > authContext > AuthContext.js

 import React, { createContext } from 'react'; const AuthContext = createContext(); export default AuthContext;

Der gerade erstellte AuthContext enthält den loading und die userToken -Zustandswerte. Derzeit haben wir im createContext , den wir im obigen Codeblock deklariert haben, hier keine Standardwerte initialisiert, sodass unser Kontext derzeit undefined ist. Ein Beispielwert des Authentifizierungskontexts könnte {loading: false, userToken: 'abcd}

Die Datei AuthState.js enthält unsere Kontext-API-Logik und ihre Zustandswerte. Hier geschriebene Funktionen können von überall in unserer App aufgerufen werden, und wenn sie Werte im Status aktualisieren, werden sie auch global aktualisiert.

Lassen Sie uns zunächst alle Importe, die wir benötigen, in diese Datei einfügen:

Kontext > AuthContext > AuthState.js

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

Wir haben den useState() Hook von ReactJS importiert, um unsere Zustände zu speichern, wir haben die AuthContext -Datei importiert, die wir oben erstellt haben, weil hier unser leerer Kontext für die Authentifizierung initialisiert wird und wir ihn verwenden müssen, wie Sie später sehen werden, während wir fortfahren , schließlich importieren wir das AsyncStorage -Paket (ähnlich wie localStorage für das Web).

AsyncStorage ist eine React Native API, mit der Sie Daten offline über das Gerät in einer React Native-Anwendung speichern können.

 ... const AuthState = (props) => { const [userToken, setUserToken] = useState(null); const [isLoading, setIsLoading] = useState(true); const onAuthentication = async() => { const USER_TOKEN = "drix1123q2" await AsyncStorage.setItem('user-token', USER_TOKEN); setUserToken(USER_TOKEN); console.warn("user has been authenticated!") } return ( <AuthContext.Provider value={{ onAuthentication, }} > {props.children} </AuthContext.Provider> ) } export default AuthState;

Im obigen Codeblock haben wir Folgendes getan:

  • Wir haben zwei Zustände für userToken und isLoading . Der Zustand userToken wird verwendet, um das in AsyncStorage gespeicherte Token zu speichern, während der Zustand isLoading verwendet wird, um den Ladestatus zu verfolgen (ursprünglich ist er auf true gesetzt). Wir werden im weiteren Verlauf mehr über die Verwendung dieser beiden Zustände erfahren.

  • Als Nächstes haben wir unsere Funktion onAuthentication() . Diese Funktion ist eine async Funktion, die aufgerufen wird, wenn in der Datei welcomeScreen.jsx auf die Anmeldeschaltfläche geklickt wird. Diese Funktion wird nur aufgerufen, wenn die E-Mail-Adresse und das Passwort, die der Benutzer angegeben hat, mit dem korrekten Benutzerdetailobjekt übereinstimmen, das wir bereitgestellt haben. Normalerweise passiert während der Authentifizierung, dass ein Token für den Benutzer generiert wird, nachdem der Benutzer am Backend mit einem Paket wie JWT authentifiziert wurde, und dieses Token an das Frontend gesendet wird. Da wir in diesem Tutorial nicht auf all das eingehen, haben wir ein statisches Token erstellt und es in einer Variablen namens USER_TOKEN .

  • Als Nächstes verwenden wir das Schlüsselwort await , um unser Benutzertoken auf AsyncStorage mit dem Namen user-token zu setzen. Die console.warn() wird nur verwendet, um zu überprüfen, ob alles richtig gelaufen ist, Sie können sie jederzeit entfernen.

  • Schließlich übergeben wir unsere onAuthenticated Funktion als Wert in unserem <AuthContext.Provider> , sodass wir von überall in unserer App auf die Funktion zugreifen und sie aufrufen können.

screens > preAuth > welcomeScreen.js

Importieren Sie zunächst useContext aus ReactJS und importieren Sie den AuthContext aus der Datei AuthContext.js .

 import React, { useState, useContext } from 'react'; import AuthContext from '../../../context/authContext/AuthContext' ...

Lassen Sie uns nun innerhalb der Funktionskomponente welcomeScreen() den Kontext verwenden, den wir erstellt haben:

 ... const WelcomeScreen = () => { const { onAuthentication } = useContext(AuthContext) const onUserAuthentication = () => { if ( email !== correctAuthenticationDetails.email || password !== correctAuthenticationDetails.password ) { alert('The email or password is incorrect') return } onAuthentication() } return ( ... ) } ...

Im obigen Codeblock haben wir die onAuthentication Funktion aus unserem AuthContext und dann innerhalb unserer onUserAuthentication() Funktion aufgerufen und die zuvor vorhandene Anweisung console.log() () entfernt.

Im Moment wird dies einen Fehler auslösen, da wir noch keinen Zugriff auf den AuthContext haben. Um den AuthContext überall in Ihrer Anwendung zu verwenden, müssen wir die Datei der obersten Ebene in unserer App mit dem AuthState (in unserem Fall ist es die App.js -Datei).

Gehen Sie zur Datei App.js und ersetzen Sie den Code dort durch diesen:

 import React from 'react'; import WelcomeScreen from './views/screens/preAuthScreens/welcomeScreen'; import AuthState from './context/authContext/AuthState' export default function App() { return ( <AuthState> <WelcomeScreen /> </AuthState> ); }

Wir sind so weit gekommen und wir sind mit diesem Abschnitt fertig. Bevor wir zum nächsten Abschnitt übergehen, in dem wir unser Routing einrichten, erstellen wir einen neuen Bildschirm. Der Bildschirm, den wir gerade erstellen, ist die Datei HomeScreen.js , die nur nach erfolgreicher Authentifizierung angezeigt werden soll.

Gehen Sie zu: Bildschirme > postAuth .

Erstellen Sie eine neue Datei namens HomeScreen.js . Hier ist der Code für die Datei HomeScreen.js :

screens > postAuth > HomeScreen.js

 import React from 'react'; import { View, Text, Button, StyleSheet } from 'react-native'; const HomeScreen = () => { const onLogout = () => { console.warn("Logout button cliked") } return ( <View style={styles.container}> <Text>Now you're authenticated! Welcome!</Text> <Button title="LOG OUT" onPress={onLogout} /> </View> ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, }) export default HomeScreen

Im Moment hat die Abmeldeschaltfläche eine Dummy console.log() . Später erstellen wir die Abmeldefunktion und übergeben sie aus unserem Kontext an den Bildschirm.

Einrichten unserer Routen

Wir müssen drei (3) Dateien in unserem Navigationsordner erstellen:

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

Nachdem Sie diese drei Dateien erstellt haben, navigieren Sie zu der gerade erstellten Datei preAuthNavigtor.js und schreiben Sie Folgendes:

navigation > preAuthNavigator.js

 import React from "react"; import { createStackNavigator } from "@react-navigation/stack"; import WelcomeScreen from "../screens/preAuthScreens/welcomeScreen"; const PreAuthNavigator = () => { const { Navigator, Screen } = createStackNavigator(); return ( <Navigator initialRouteName="Welcome"> <Screen name="Welcome" component={WelcomeScreen} /> </Navigator> ) } export default PreAuthNavigator;

In der obigen Datei haben wir Folgendes getan:

  • Wir haben den createStackNavigator aus @react-navigation/stack importiert, den wir für unsere Stack-Navigation verwenden. Der createStackNavigator bietet Ihrer App die Möglichkeit, zwischen Bildschirmen zu wechseln, wobei jeder neue Bildschirm auf einem Stapel platziert wird. Standardmäßig ist der Stack-Navigator so konfiguriert, dass er das vertraute Aussehen und Verhalten von iOS und Android hat: Neue Bildschirme werden bei iOS von rechts eingeschoben, bei Android von unten eingeblendet. Klicken Sie hier, wenn Sie mehr über den Stack-Navigator in React Native erfahren möchten.
  • Wir haben Navigator und Screen von createStackNavigator() .
  • In unserer return-Anweisung haben wir unsere Navigation mit dem <Navigator/> und unseren Bildschirm mit dem <Screen/> erstellt. Das bedeutet, dass wir, wenn wir mehrere Bildschirme hatten, auf die vor der Authentifizierung zugegriffen werden kann, hier mehrere <Screen/> -Tags haben, die sie darstellen.
  • Schließlich exportieren wir unsere PreAuthNavigator Komponente.

Lassen Sie uns etwas Ähnliches für die Datei postAuthNavigator.js tun.

navigation > postAuthNavigator.js

 import React from "react"; import { createStackNavigator } from "@react-navigation/stack"; import HomeScreen from "../screens/postAuthScreens/HomeScreen"; const PostAuthNavigator = () => { const { Navigator, Screen} = createStackNavigator(); return ( <Navigator initialRouteName="Home"> <Screen name="Home" component={HomeScreen} /> </Navigator> ) } export default PostAuthNavigator;

Wie wir im obigen Code sehen, ist der einzige Unterschied zwischen preAuthNavigator.js und postAuthNavigator.js der gerenderte Bildschirm. Während der erste den WelcomeScreen übernimmt, übernimmt postAuthNavigator.js den HomeScreen .

Um unsere AppNavigator.js zu erstellen, müssen wir ein paar Dinge erstellen.

Da wir in AppNavigator.js wechseln und prüfen, welche Route für den Zugriff durch den Benutzer verfügbar ist, benötigen wir mehrere Bildschirme, damit dies ordnungsgemäß funktioniert. Lassen Sie uns die Dinge skizzieren, die wir zuerst erstellen müssen:

  1. TransitionScreen.js
    Während die App entscheidet, welche Navigation sie montieren wird, möchten wir, dass ein Übergangsbildschirm angezeigt wird. Normalerweise ist der Übergangsbildschirm ein Lade-Spinner oder eine andere benutzerdefinierte Animation, die für die App ausgewählt wurde, aber in unserem Fall verwenden wir ein einfaches <Text/> -Tag, um anzuzeigen, dass loading… .
  2. checkAuthenticationStatus()
    Diese Funktion wird aufgerufen, um den Authentifizierungsstatus zu überprüfen, der bestimmt, welcher Navigationsstapel bereitgestellt wird. Wir werden diese Funktion in unserem Kontext erstellen und in der Appnavigator.js verwenden .

Lassen Sie uns nun fortfahren und unsere TransitionScreen.js -Datei erstellen.

Bildschirme > TransitionScreen.js

 import React from 'react'; import { Text, View } from 'react-native'; const TransitionScreen = () => { return ( <View> <Text>Loading...</Text> </View> ) } export default TransitionScreen

Unser Übergangsbildschirm ist nur ein einfacher Bildschirm, der Ladetext anzeigt. Wir werden sehen, wo wir dies verwenden können, wenn wir in diesem Artikel fortfahren.

Als nächstes gehen wir zu unserer AuthState.js und schreiben unsere checkAuthenticationStatus() :

Kontext > authContext > AuthState.js

 import React, { useState, useEffect } from 'react'; import AuthContext from './AuthContext'; import AsyncStorage from '@react-native-community/async-storage'; const AuthState = (props) => { const [userToken, setUserToken] = useState(null); const [isLoading, setIsLoading] = useState(true); ... useEffect(() => { checkAuthenticationStatus() }, []) const checkAuthenticationStatus = async () => { try { const returnedToken = await AsyncStorage.getItem('user-toke n'); setUserToken(returnedToken); console.warn('User token set to the state value) } catch(err){ console.warn(`Here's the error that occured while retrievin g token: ${err}`) } setIsLoading(false) } const onAuthentication = async() => { ... } return ( <AuthContext.Provider value={{ onAuthentication, userToken, isLoading, }} > {props.children} </AuthContext.Provider> ) } export default AuthState;

Im obigen Codeblock haben wir die Funktion checkAuthenticationStatus() . In unserer Funktion tun wir Folgendes:

  • Wir haben das Schlüsselwort await verwendet, um unser Token von AsyncStorage zu erhalten. Wenn bei AsyncStorage kein Token bereitgestellt wird, wird null zurückgegeben. Unser anfänglicher userToken -Status wird ebenfalls auf null gesetzt.
  • Wir verwenden setUserToken , um unseren zurückgegebenen Wert von AsyncStorage als unser neues userToken . Wenn der zurückgegebene Wert null ist, bedeutet dies, dass unser userToken null bleibt.
  • Nach dem Block try{}…catch(){} setzen wir isLoading auf false, da die Funktion zum Überprüfen des Authentifizierungsstatus abgeschlossen ist. Wir benötigen den Wert von isLoading , um zu wissen, ob wir den TransitionScreen weiterhin anzeigen sollen oder nicht. Es lohnt sich, einen Fehler festzulegen, wenn beim Abrufen des Tokens ein Fehler auftritt, damit wir dem Benutzer eine Schaltfläche „Wiederholen“ oder „Erneut versuchen“ anzeigen können, wenn der Fehler auftritt.
  • Immer wenn AuthState , möchten wir den Authentifizierungsstatus überprüfen, also verwenden wir dazu den useEffect() ReactJS-Hook. Wir rufen unsere Funktion checkAuthenticationStatus() innerhalb des useEffect() auf und setzen den Wert von isLoading auf false , wenn es fertig ist.
  • Schließlich fügen wir unsere Zustände zu unseren <AuthContext.Provider/> Werten hinzu, damit wir von überall in unserer App, die von der Kontext-API abgedeckt wird, darauf zugreifen können.

Jetzt, da wir unsere Funktion haben, ist es an der Zeit, zu unserer AppNavigator.js zurückzukehren und den Code zum Mounten eines bestimmten Stack-Navigators basierend auf dem Authentifizierungsstatus zu schreiben:

Navigation > AppNavigator.js

Zuerst importieren wir alles, was wir für unsere AppNavigator.js benötigen.

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

Nachdem wir nun alle unsere Importe haben, erstellen wir die Funktion AppNavigator() .

 ... const AppNavigator = () => { } export default AppNavigator

Als nächstes werden wir nun den Inhalt unserer Funktion AppNavigator() schreiben:

 import React, { useState, useEffect, useContext } from "react"; import PreAuthNavigator from "./preAuthNavigator"; import PostAuthNavigator from "./postAuthNavigator"; import { NavigationContainer } from "@react-navigation/native" import { createStackNavigator } from "@react-navigation/stack"; import AuthContext from "../../context/authContext/AuthContext"; import TransitionScreen from "../screens/transition"; const AppNavigator = () => { const { Navigator, Screen } = createStackNavigator(); const authContext = useContext(AuthContext); const { userToken, isLoading } = authContext; if(isLoading) { return <TransitionScreen /> } return ( <NavigationContainer> <Navigator> { userToken == null ? ( <Screen name="PreAuth" component={PreAuthNavigator} options={{ header: () => null }} /> ) : ( <Screen name="PostAuth" component={PostAuthNavigator} options={{ header: () => null }} /> ) } </Navigator> </NavigationContainer> ) } export default AppNavigator

Im obigen Codeblock ist hier ein Überblick darüber, was wir getan haben:

  • Wir haben einen Stapelnavigator erstellt und den Navigator und den Screen daraus destrukturiert.
  • Wir haben das userToken und das isLoading aus unserem AuthContext
  • Wenn der AuthState wird, wird dort der checkAuthenticationStatus() im useEffecct Hook aufgerufen. Wir verwenden die if -Anweisung, um zu überprüfen, ob isLoading true ist. Wenn dies true ist, ist der Bildschirm, den wir zurückgeben, unser <TransitionScreen /> , den wir zuvor erstellt haben, da die Funktion checkAuthenticationStatus() noch nicht vollständig ist.
  • Sobald unser checkAuthenticationStatus() abgeschlossen ist, wird isLoading auf false gesetzt und wir geben unsere Hauptnavigationskomponenten zurück.
  • Der NavigationContainer wurde aus @react-navigation/native importiert. Es wird nur einmal im Hauptnavigator der obersten Ebene verwendet. Beachten Sie, dass wir dies nicht in preAuthNavigator.js oder postAuthNavigator.js verwenden.
  • In unserem AppNavigator() erstellen wir noch einen Stack-Navigator. Wenn das von unserer Context-API erhaltene userToken null ist, mounten wir den PreAuthNavigator , wenn sein Wert etwas anderes ist (was bedeutet, dass AsyncStorage.getItem() in checkAuthenticationStatus() einen tatsächlichen Wert zurückgegeben hat), dann mounten wir den PostAuthNavigator . Unser bedingtes Rendering erfolgt mit dem ternären Operator.

Jetzt haben wir unsere AppNavigator.js eingerichtet. Als nächstes müssen wir unseren AppNavigator an unsere App.js- Datei übergeben.

Übergeben wir unseren AppNavigator an die App.js -Datei:

App.js

 ... import AppNavigator from './views/navigation/AppNavigator'; ... return ( <AuthState> <AppNavigator /> </AuthState> );

Sehen wir uns nun an, wie unsere App im Moment aussieht:

Folgendes passiert, wenn Sie beim Versuch, sich anzumelden, falsche Anmeldedaten angeben:

Hinzufügen der Abmeldefunktion

An diesem Punkt ist unser Authentifizierungs- und Routenauswahlprozess abgeschlossen. Das einzige, was für unsere App übrig bleibt, ist das Hinzufügen der Abmeldefunktion.

Die Abmeldeschaltfläche befindet sich in der Datei HomeScreen.js . Wir haben eine onLogout() Funktion an das onPress Attribut der Schaltfläche übergeben. Im Moment haben wir eine einfache console.log() in unserer Funktion, aber das wird sich in Kürze ändern.

Gehen wir nun zu unserer AuthState.js und schreiben die Funktion zum Abmelden. Diese Funktion löscht einfach den AsyncStorage in dem das Benutzertoken gespeichert ist.

Kontext > authContext > AuthState.js

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

Das userSignout() ist eine asynchrone Funktion, die das user-token aus unserem AsyncStorage .

Jetzt müssen wir jedes Mal, wenn auf die Abmeldeschaltfläche geklickt wird, die Funktion userSignout() in unserer HomeScreen.js aufrufen .

Gehen wir zu unserer HomeScreen.js und verwenden Sie die userSignout() von unserem 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 ( <View style={styles.container}> <Text>Now you're authenticated! Welcome!</Text> <Button title="LOG OUT" onPress={onLogout} /> </View> ) } ...

Im obigen Codeblock haben wir den useContext Hook aus ReactJS importiert, dann haben wir unseren AuthContext importiert. Als nächstes haben wir die userSignout Funktion aus unserem AuthContext und diese userSignout() Funktion wird in unserer onLogout() -Funktion aufgerufen.

Wenn jetzt auf unsere Abmeldeschaltfläche geklickt wird, wird das Benutzertoken in unserem AsyncStorage gelöscht.

Voila! Unser gesamter Prozess ist abgeschlossen.

Folgendes passiert, wenn Sie nach der Anmeldung auf die Schaltfläche „Zurück“ klicken:

Drücken Sie die Zurück-Taste, nachdem Sie sich bei der App angemeldet haben.

Folgendes passiert, wenn Sie nach dem Abmelden die Zurück-Taste drücken:

Drücken Sie die Zurück-Taste, nachdem Sie sich von der App abgemeldet haben.

Hier sind einige unterschiedliche Verhaltensweisen, die wir bemerken, wenn wir dieses Muster in unserem Navigationsstapelwechsel verwenden:

  1. Sie werden feststellen, dass wir nirgendwo navigation.navigate() oder navigation.push() verwenden mussten, um nach der Anmeldung zu einer anderen Route zu gehen. Sobald unser Status mit dem Benutzertoken aktualisiert wurde, wird der gerenderte Navigationsstapel automatisch geändert.
  2. Das Drücken der Zurück-Taste auf Ihrem Gerät nach erfolgreicher Anmeldung bringt Sie nicht zurück zur Anmeldeseite, sondern schließt die App vollständig. Dieses Verhalten ist wichtig, da Sie nicht möchten, dass der Benutzer zur Anmeldeseite zurückkehren kann, es sei denn, er meldet sich von der App ab. Das Gleiche gilt für das Abmelden – sobald sich der Benutzer abgemeldet hat, kann er nicht mit der Zurück-Taste zum HomeScreen -Bildschirm zurückkehren, sondern die App wird geschlossen.

Fazit

In vielen Apps ist die Authentifizierung einer der wichtigsten Teile, da sie bestätigt, dass die Person, die versucht, Zugang zu geschützten Inhalten zu erhalten, das Recht hat, auf die Informationen zuzugreifen. Zu lernen, wie man es richtig macht, ist ein wichtiger Schritt beim Erstellen einer großartigen, intuitiven und einfach zu bedienenden/navigierbaren Anwendung.

Aufbauend auf diesem Code sind hier einige Dinge, die Sie hinzufügen könnten:

  • Formularvalidierung zur Validierung von Eingabefeldern. Sehen Sie sich die React Native-Formularvalidierung mit Formik und Yup an.
  • Firebase-Authentifizierung zur Integration der Authentifizierung mit Gmail, Github, Facebook, Twitter oder Ihrer benutzerdefinierten Oberfläche. Sehen Sie sich React Native Firebase an.
  • Codekonzepte für Designer: Authentifizierung und Autorisierung.

Hier sind auch einige wichtige Ressourcen, die ich gefunden habe, die Sie mehr über Authentifizierung, Sicherheit und wie man es richtig macht, aufklären werden:

Ressourcen

  • Reagieren Sie nativ: Ablauf der Benutzerauthentifizierung erklärt
  • 10 Best Practices für React-Sicherheit
  • Authentifizierungsmethoden, die den nächsten Verstoß verhindern können
  • Sehen Sie sich hier einen Live-Build/eine Vorschau unserer Anwendung an;
  • Sehen Sie sich das Projekt auf GitHub an.