ReactNativeでのナビゲーションルートのマウントとアンマウントの処理

公開: 2022-03-10
クイックサマリー↬多くの場合、ユーザー認証の前後に2つの異なるナビゲーションスタックのセットが必要です。 通常、より多くのコンテンツを表示するには、何らかの方法で認証される必要があります。 React Nativeで満たされた条件に基づいて、ナビゲーションスタックをマウントおよびアンマウントする方法を見てみましょう。

この記事では、ReactNativeでのナビゲーションルートのマウントとアンマウントについて説明します。 アプリの予想される動作は、認証条件が満たされると、ログインしたユーザーのみが新しいナビゲーションルートのセットを利用できるようにする一方で、認証前に表示されていた他の画面は削除され、ユーザーがアプリケーションからサインアウトします。

アプリのセキュリティのために、保護されたルートは、許可されていない人からのアクセスを制限しながら、アプリの特定の情報/コンテンツのみを特定のユーザーに表示する方法を提供します。

このプロジェクトでは、多くのセットアップについて心配することなく、目前の問題に集中するのに役立つため、Expoと協力します。 この記事のまったく同じ手順は、ベアのReactNativeアプリケーションでも実行できます。

このチュートリアルを実行するには、 JavaScriptとReactNativeにある程度精通している必要があります。 すでに知っておくべき重要なことをいくつか紹介します。

  • React Nativeのカスタムコンポーネント(コンポーネントを作成し、コンポーネントで小道具を受け取り、渡し、使用する方法)。 続きを読む。
  • Reactナビゲーション。 続きを読む。
  • ReactNativeのスタックナビゲーター。 続きを読む。
  • React Native Coreコンポーネント( <View/><Text/>など)の基本的な知識。 続きを読む。
  • AsyncStorage 。 続きを読む。
  • コンテキストAPI。 続きを読む。

プロジェクトのセットアップと基本認証

expoの使用に不慣れで、expoのインストール方法がわからない場合は、公式ドキュメントにアクセスしてください。 インストールが完了したら、コマンドプロンプトからexpoを使用して新しいReactNativeプロジェクトを初期化します。

 expo init navigation-project

基本設定をどのようにするかを選択するためのいくつかのオプションが表示されます。

ReactNativeプロジェクトの基本設定
(大プレビュー)

この場合、最初のオプションを選択して、プロジェクトを空白のドキュメントとして設定しましょう。 ここで、JavaScriptの依存関係のインストールが完了するまで待ちます。

アプリをセットアップしたら、ディレクトリを新しいプロジェクトディレクトリに変更して、お気に入りのコードエディタで開くことができます。 AsyncStorageに使用するライブラリとナビゲーションライブラリをインストールする必要があります。 ターミナルのフォルダディレクトリ内に、上記のコマンドを貼り付け、テンプレートを選択して( blankでも機能します)、プロジェクトの依存関係をインストールします。

これらの依存関係のそれぞれが何のためにあるかを見てみましょう:

  • @ react-native-community / async-storage
    Web上のlocalStorageと同様に、キーと値のペアでデバイス上のデータを永続化するためのReactNativeAPIです。
  • @ react-native-community / masked-view、react-native-screens、react-native-gesture-handle
    これらの依存関係は、ほとんどのナビゲーターがアプリでナビゲーション構造を作成するために使用するコアユーティリティです。 (詳細については、React Nativeナビゲーションの開始を参照してください。)
  • @ react-navigation / native
    これは、ReactNativeナビゲーションの依存関係です。
  • @ react-navigation / stack
    これは、ReactNativeでのスタックナビゲーションの依存関係です。
 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

アプリケーションを起動するには、ターミナルのアプリディレクトリからexpo startを使用します。 アプリが起動したら、携帯電話からexpoアプリを使用してバーコードをスキャンし、アプリケーションを表示できます。Androidエミュレーター/ IOSシミュレーターを使用している場合は、expo開発者ツールからアプリを開くことができます。 Expoアプリケーションを起動すると、ブラウザで開きます。 この記事の画像の例では、Genymotionsを使用して結果を確認します。 Genymotionsでの最終結果は次のようになります。

Genymotionsの最終結果
(大プレビュー)

フォルダ構造

最初からフォルダ構造を作成して、作業を進めていくときに簡単に操作できるようにします。

最初に2つのフォルダが必要です。

  • 環境
    このフォルダーは、グローバル状態管理のためにContext APIを使用するため、アプリケーション全体のコンテキストを保持します。
  • ビュー
    このフォルダーには、ナビゲーションフォルダーとさまざまな画面のビューの両方が保持されます。

先に進み、プロジェクトディレクトリに2つのフォルダを作成します。

コンテキストフォルダー内に、 authContextというフォルダーを作成し、 authContextフォルダー内に2つのファイルを作成します。

  • AuthContext.js
  • AuthState.js

Context APIの使用を開始するときに、これらのファイルが必要になります。

次に、作成したビューフォルダーに移動し、その中にさらに2つのフォルダーを作成します。

  • ナビゲーション
  • 画面

これで、まだ完了していません。screensフォルダー内に、さらに2つのフォルダーを作成します。

  • postAuthScreens
  • preAuthScreens

フォルダの設定に正しく従った場合、現時点でのフォルダ構造は次のようになります。

フォルダ構造
(大プレビュー)
ジャンプした後もっと! 以下を読み続けてください↓

最初の画面の作成

次に、最初の画面を作成し、 preAuthScreensフォルダー内でwelcomeScreen.jsと呼びます。

preAuthScreens> welcomeScreen.js

これが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

上記のコードブロックで行ったことは次のとおりです。

まず、React Nativeライブラリから必要なもの、つまりViewTextButtonTextInputをインポートしました。 次に、機能コンポーネントWelcomeScreenを作成しました。

React NativeからStyleSheetをインポートし、それを使用してヘッダーと<TextInput />のスタイルを定義したことに気付くでしょう。

最後に、コードの下部にあるWelcomeScreenコンポーネントをエクスポートします。

これでuseStateフックを使用して入力の値を格納し、入力フィールドで変更が発生するたびに状態を更新することで、このコンポーネントを期待どおりに機能させましょう。 また、関数を保持するために後で必要になるため、ReactからuseCallbackフックをインポートします。

まず、 WelcomeScreenコンポーネントを使用している間に、ReactからuseStateuseCallbackをインポートする必要があります。

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

ここで、 WelcomeScreen機能コンポーネント内で、電子メールとパスワードの2つの状態をそれぞれ作成しましょう。

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

次に、 <TextInput />フィールドを変更して、それぞれの状態から値を取得し、入力の値が更新されたときに状態を更新する必要があります。

 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> ) } ...

上記のコードでは、これが私たちがしたことです:

  • それぞれの状態を指すように、各テキスト入力のvalueを作成しました。
  • onChangeTextハンドラーをテキスト入力に追加しました。 これは、入力フィールドに新しい値が入力または削除されるたびに起動します。
  • 2つの引数を受け入れるonInputChange関数を呼び出しました。
    • 現在のvalueは、 onChangeTextハンドラーによって提供されます。
    • 更新する必要のある状態のセッター(最初の入力フィールドにはsetEmailを渡し、2番目の入力フィールドにはsetPasswordを渡します)。
    • 最後に、 onInputChange関数を記述します。この関数は、それぞれの状態を新しい値で更新するという1つのことだけを実行します。

次に取り組む必要があるのは、フォーム送信のボタンがクリックされるたびに呼び出されるonUserAuthentication()関数です。

理想的には、ユーザーはすでにアカウントを作成している必要があり、ログインには、ユーザーが存在することを確認してからトークンをユーザーに割り当てるための何らかのバックエンドロジックが含まれます。 この場合、バックエンドを使用していないため、正しいユーザーログインの詳細を保持するオブジェクトを作成し、ユーザーが入力した値が、 emailpasswordのログインオブジェクトからの固定値と一致する場合にのみユーザーを認証します。作成。

これを行うために必要なコードは次のとおりです。

 ... 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 ( ... ) } ...

上記のコードで最初に気付くのは、 WelcomeScreen()機能コンポーネントの外部でcorrectAuthenticationDetails (ユーザーが提供することが期待される正しいログイン詳細を保持するオブジェクト)を定義したことです。

次に、 onUserAuthentication()関数の内容を記述し、条件ステートメントを使用して、それぞれの状態で保持されているemailまたはpasswordが、オブジェクトで指定したものと一致しないかどうかを確認しました。

これまでに行ったことを確認したい場合は、次のようにWelcomeScreenコンポーネントをApp.jsにインポートします。

App.jsファイルを開き、これを配置して、コード全体を次のように置き換えます。

 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> ); }

上記のコードをよく見ると、 WelcomeScreenコンポーネントをインポートし、それをApp()関数で使用したことがわかります。

WelcomeScreenの結果は次のようになります。

WelcomeScreenの結果
(大プレビュー)

WelcomeScreenコンポーネントの構築が完了したので、先に進んで、グローバル状態を管理するためのContextAPIの使用を開始しましょう。

なぜコンテキストAPIなのか?

Context APIを使用すると、ReactJSに追加のライブラリをインストールする必要がなく、セットアップのストレスが少なく、ReactJSでグローバル状態を処理する最も一般的な方法の1つです。 軽量の状態管理には、これは良い選択です。

コンテキストの作成

思い出してください。以前にコンテキストフォルダを作成し、その中にauthContextと呼ばれるサブフォルダを作成しました。

次に、 authContextフォルダー内のAuthContext.jsファイルに移動して、コンテキストを作成します。

コンテキスト>authContext>AuthContext.js

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

作成したAuthContextは、 loading状態の値とuserToken状態の値を保持します。 現在、上記のコードブロックで宣言したcreateContextでは、ここでデフォルト値を初期化していないため、コンテキストは現在undefinedです。 認証コンテキストの値の例は、 {loading: false, userToken: 'abcd}ようになります。

AuthState.jsファイルは、コンテキストAPIロジックとその状態値を保持します。 ここで記述された関数は、アプリ内のどこからでも呼び出すことができ、状態の値を更新すると、グローバルにも更新されます。

まず、このファイルに必要なすべてのインポートを取り込みましょう。

コンテキスト>AuthContext>AuthState.js

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

状態を保持するためにReactJSからuseState()フックをインポートしました。これは、認証用の空のコンテキストが初期化される場所であり、後で説明するように使用する必要があるため、上記で作成したAuthContextファイルをインポートしました。 、最後にAsyncStorageパッケージをインポートします(WebのlocalStorageと同様)。

AsyncStorageはReactNativeAPIであり、ReactNativeアプリケーションのデバイスを介してデータをオフラインで永続化できます。

 ... 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;

上記のコードブロックで、私たちが行ったことは次のとおりです。

  • userTokenisLoadingの2つの状態を宣言しました。 userToken状態は、 AsyncStorageに保存されたトークンを格納するために使用され、 isLoading状態は、ロードステータスを追跡するために使用されます(最初はtrueに設定されています)。 先に進むにつれて、これら2つの状態の使用について詳しく説明します。

  • 次に、 onAuthentication()関数を作成しました。 この関数は、 welcomeScreen.jsxファイルからログインボタンがクリックされたときに呼び出されるasync関数です。 この関数は、ユーザーが指定した電子メールとパスワードが、指定した正しいユーザー詳細オブジェクトと一致する場合にのみ呼び出されます。 通常、認証中に発生するのは、ユーザーがJWTなどのパッケージを使用してバックエンドで認証された後にユーザーのトークンが生成され、このトークンがフロントエンドに送信されることです。 このチュートリアルではそのすべてを説明するわけではないため、静的トークンを作成し、 USER_TOKENという変数に保持しました。

  • 次に、 awaitキーワードを使用して、ユーザートークンをuser-tokenという名前のAsyncStorageに設定します。 console.warn()ステートメントは、すべてが正常に行われたことを確認するために使用されます。いつでも削除できます。

  • 最後に、 onAuthenticated関数を<AuthContext.Provider>内の値として渡し、アプリのどこからでも関数にアクセスして呼び出すことができるようにします。

画面>preAuth>welcomeScreen.js

まず、 useContextからuseContextをインポートし、 AuthContextファイルからAuthContext.jsをインポートします。

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

ここで、 welcomeScreen()機能コンポーネント内で、作成したコンテキストを使用してみましょう。

 ... 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 ( ... ) } ...

上記のコードブロックでは、AuthContextからonAuthentication関数をAuthContextしてから、 onUserAuthentication()関数内で呼び出し、以前にあったconsole.log()ステートメントを削除しました。

現在、 AuthContextにまだアクセスできないため、これはエラーをスローします。 アプリケーションの任意の場所でAuthContextを使用するには、アプリの最上位ファイルをAuthState (この場合はApp.jsファイル)でラップする必要があります。

App.jsファイルに移動し、そこにあるコードを次のように置き換えます。

 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> ); }

ここまで来て、このセクションは終了です。 ルーティングを設定する次のセクションに進む前に、新しい画面を作成しましょう。 これから作成する画面は、認証が成功した後にのみ表示されるはずのHomeScreen.jsファイルになります。

画面>postAuthに移動します。

HomeScreen.jsという名前の新しいファイルを作成します。 HomeScreen.jsファイルのコードは次のとおりです。

画面>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

今のところ、ログアウトボタンにはダミーのconsole.log()ステートメントがあります。 後で、ログアウト機能を作成し、コンテキストから画面に渡します。

ルートの設定

ナビゲーションフォルダ内に3つのファイルを作成する必要があります。

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

これらの3つのファイルを作成したら、作成したpreAuthNaviagtor.jsファイルに移動して、次のように記述します。

ナビゲーション>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;

上記のファイルで、私たちが行ったことは次のとおりです。

  • スタックナビゲーションに使用している@react-navigation/stackからcreateStackNavigatorをインポートしました。 createStackNavigatorは、新しい各画面がスタックの一番上に配置されている画面間をアプリが移行する方法を提供します。 デフォルトでは、スタックナビゲーターは、おなじみのiOSとAndroidのルックアンドフィールを持つように構成されています。新しい画面は、iOSでは右からスライドインし、Androidでは下からフェードインします。 React Nativeのスタックナビゲーターについて詳しく知りたい場合は、ここをクリックしてください。
  • createStackNavigator()からNavigatorScreenを分解しました。
  • returnステートメントでは、 <Navigator/>を使用してナビゲーションを作成し、 <Screen/>を使用して画面を作成しました。 これは、認証前にアクセスできる複数の画面がある場合、それらを表す複数の<Screen/>タグがここにあることを意味します。
  • 最後に、 PreAuthNavigatorコンポーネントをエクスポートします。

postAuthNavigator.jsファイルに対しても同様のことを行いましょう。

ナビゲーション>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;

上記のコードでわかるように、 preAuthNavigator.jspostAuthNavigator.jsの唯一の違いは、レンダリングされる画面です。 最初のものはWelcomeScreenを取りますが、 HomeScreenHomeScreenを取ります。

AppNavigator.jsを作成するには、いくつかのものを作成する必要があります。

AppNavigator.jsは、ユーザーがアクセスできるルートを切り替えて確認する場所であるため、これを正しく機能させるには、いくつかの画面を配置する必要があります。最初に作成する必要があるものの概要を説明します。

  1. TransitionScreen.js
    アプリがマウントするナビゲーションを決定している間、トランジション画面を表示する必要があります。 通常、トランジション画面は、アプリ用に選択された読み込みスピナーまたはその他のカスタムアニメーションになりますが、この場合、基本的な<Text/>タグを使用してloading…
  2. checkAuthenticationStatus()
    この関数は、どのナビゲーションスタックがマウントされるかを決定する認証ステータスをチェックするために呼び出すものです。 この関数をコンテキストで作成し、 Appnavigator.jsで使用します。

それでは、先に進んでTransitionScreen.jsファイルを作成しましょう。

画面> TransitionScreen.js

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

トランジション画面は、テキストの読み込みを表示する単純な画面です。 この記事を進めるにつれ、これをどこで使用するかがわかります。

次に、 AuthState.jsに移動して、 checkAuthenticationStatus()を記述します。

コンテキスト>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;

上記のコードブロックでは、関数checkAuthenticationStatus()を記述しました。 私たちの関数では、これが私たちがしていることです:

  • awaitキーワードを使用して、 AsyncStorageからトークンを取得しました。 AsyncStorageでは、トークンが提供されていない場合、 nullを返します。 また、 userTokenの初期状態もnullに設定されています。
  • setUserTokenを使用して、 setUserTokenからの戻り値を新しいAsyncStorageとして設定しuserToken 。 戻り値がnullの場合、 userTokennullのままであることを意味します。
  • try{}…catch(){}ブロックの後、認証ステータスをチェックする関数が完了したため、 isLoadingをfalseに設定します。 TransitionScreenを表示する必要があるかどうかを知るには、 isLoadingの値が必要です。 トークンの取得中にエラーが発生した場合は、エラーが発生したときにユーザーに「再試行」または「再試行」ボタンを表示できるように、エラーを設定することを検討する価値があります。
  • AuthStateがマウントされるたびに、認証ステータスを確認する必要があるため、 useEffect() ReactJSフックを使用してこれを行います。 useEffect()フック内でcheckAuthenticationStatus()関数を呼び出し、完了したらisLoadingの値をfalseに設定します。
  • 最後に、状態を<AuthContext.Provider/>値に追加して、ContextAPIの対象となるアプリ内のどこからでも状態にアクセスできるようにします。

関数ができたので、 AppNavigator.jsに戻って、認証ステータスに基づいて特定のスタックナビゲーターをマウントするためのコードを記述します。

ナビゲーション>AppNavigator.js

まず、 AppNavigator.jsに必要なものをすべてインポートします。

 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";

すべてのインポートが完了したので、 AppNavigator()関数を作成しましょう。

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

次に、 AppNavigator()関数のコンテンツを記述します。

 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

上記のコードブロックで、私たちが行ったことの概要を次に示します。

  • スタックナビゲーターを作成し、そこからNavigatorScreenを分解しました。
  • isLoadingからuserTokenAuthContextをインポートしました
  • AuthStateがマウントされると、 useEffecctフックでcheckAuthenticationStatus()が呼び出されます。 ifステートメントを使用してisLoadingtrueかどうかを確認しますtrueの場合、 checkAuthenticationStatus()関数がまだ完了していないため、返される画面は前に作成した<TransitionScreen />です。
  • checkAuthenticationStatus()が完了すると、 isLoadingfalseに設定され、メインのナビゲーションコンポーネントが返されます。
  • NavigationContainer@react-navigation/nativeからインポートされました。 メインのトップレベルナビゲーターで1回だけ使用されます。 preAuthNavigator.jsまたはpostAuthNavigator.jsではこれを使用していないことに注意してください。
  • AppNavigator()では、スタックナビゲーターを作成します。 Context APIから取得したuserTokennullの場合、 PreAuthNavigatorをマウントします。その値が他の値である場合(つまり、 AsyncStorage.getItem()checkAuthenticationStatus()が実際の値を返した場合)、 PostAuthNavigatorをマウントします。 条件付きレンダリングは、三項演算子を使用して行われます。

これで、 AppNavigator.jsを設定しました。 次に、 AppNavigatorApp.jsファイルに渡す必要があります。

AppNavigatorApp.jsファイルに渡します。

App.js

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

今のところ、私たちのアプリがどのように見えるか見てみましょう:

ログインしようとしているときに間違ったクレデンシャルを指定すると、次のようになります。

ログアウト機能の追加

この時点で、認証とルート選択のプロセスは完了です。 私たちのアプリに残されているのは、ログアウト機能を追加することだけです。

ログアウトボタンはHomeScreen.jsファイルにあります。 onLogout()関数をボタンのonPress属性に渡しました。 今のところ、関数には単純なconsole.log()ステートメントがありますが、しばらくすると変更されます。

それでは、 AuthState.jsに移動して、ログアウト用の関数を記述しましょう。 この関数は、ユーザートークンが保存されているAsyncStorageをクリアするだけです。

コンテキスト>authContext>AuthState.js

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

userSignout()は、 AsyncStorageからuser-tokenを削除する非同期関数です。

次に、ログアウトボタンがクリックされるたびに、 HomeScreen.jsuserSignout()関数を呼び出す必要があります。

HomeScreen.jsに移動し、 AuthContextからAuthContext userSignout()を使用してみましょう。

画面>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> ) } ...

上記のコードブロックでは、ReactJSからuseContextフックをインポートしてから、AuthContextをインポートしました。 次に、AuthContextからuserSignout関数をAuthContextし、このuserSignout()関数をonLogout() ()関数で呼び出します。

これで、ログアウトボタンがクリックされるたびに、 AsyncStorageのユーザートークンがクリアされます。

出来上がり! プロセス全体が終了しました。

ログイン後に戻るボタンを押すと、次のようになります。

アプリにログインした後、戻るボタンを押します。

ログアウト後に戻るボタンを押すと、次のようになります。

アプリからログアウトした後、戻るボタンを押します。

ナビゲーションスタックの切り替えでこのパターンを使用すると、いくつかの異なる動作が見られます。

  1. ログイン後に別のルートに移動するためにnavigation.navigate()またはnavigation.push()を使用する必要がある場所がなかったことに気付くでしょう。 状態がユーザートークンで更新されると、レンダリングされるナビゲーションスタックは自動的に変更されます。
  2. ログインに成功した後にデバイスの戻るボタンを押しても、ログインページに戻ることはできません。代わりに、アプリが完全に閉じます。 ユーザーがアプリからログアウトする場合を除いて、ユーザーがログインページに戻れないようにするため、この動作は重要です。 同じことがログアウトにも当てはまります。ユーザーがログアウトすると、戻るボタンを使用してHomeScreen画面画面に戻ることはできませんが、代わりにアプリが閉じます。

結論

多くのアプリでは、保護されたコンテンツにアクセスしようとしている人が情報にアクセスする権利を持っていることを確認するため、認証は最も重要な部分の1つです。 それを正しく行う方法を学ぶことは、アプリケーションを優れた、直感的で、使いやすく/ナビゲートするための重要なステップです。

このコードに基づいて、追加を検討する可能性のあるものをいくつか示します。

  • 入力フィールドを検証するためのフォーム検証。 FormikとYupを使用したReactNativeフォームの検証を確認してください。
  • Gmail、Github、Facebook、Twitter、またはカスタムインターフェースと認証を統合するためのFirebase認証。 ReactNativeFirebaseをチェックしてください。
  • 設計者向けのコード概念:認証と承認。

また、認証、セキュリティ、およびそれを正しく行う方法についてより多くのことを教えてくれる、私が見つけたいくつかの重要なリソースもあります。

資力

  • React Native:ユーザー認証フローの説明
  • 10Reactセキュリティのベストプラクティス
  • 次の違反を防ぐことができる認証方法
  • ここでアプリケーションのライブビルド/プレビューを表示します。
  • GitHubでプロジェクトを表示します。