ReactNativeでのナビゲーションルートのマウントとアンマウントの処理
公開: 2022-03-10この記事では、ReactNativeでのナビゲーションルートのマウントとアンマウントについて説明します。 アプリの予想される動作は、認証条件が満たされると、ログインしたユーザーのみが新しいナビゲーションルートのセットを利用できるようにする一方で、認証前に表示されていた他の画面は削除され、ユーザーがアプリケーションからサインアウトします。
アプリのセキュリティのために、保護されたルートは、許可されていない人からのアクセスを制限しながら、アプリの特定の情報/コンテンツのみを特定のユーザーに表示する方法を提供します。
このプロジェクトでは、多くのセットアップについて心配することなく、目前の問題に集中するのに役立つため、Expoと協力します。 この記事のまったく同じ手順は、ベアのReactNativeアプリケーションでも実行できます。
このチュートリアルを実行するには、 JavaScriptとReactNativeにある程度精通している必要があります。 すでに知っておくべき重要なことをいくつか紹介します。
- React Nativeのカスタムコンポーネント(コンポーネントを作成し、コンポーネントで小道具を受け取り、渡し、使用する方法)。 続きを読む。
- Reactナビゲーション。 続きを読む。
- ReactNativeのスタックナビゲーター。 続きを読む。
- React Native Coreコンポーネント(
<View/>
、<Text/>
など)の基本的な知識。 続きを読む。 -
AsyncStorage
。 続きを読む。 - コンテキストAPI。 続きを読む。
プロジェクトのセットアップと基本認証
expoの使用に不慣れで、expoのインストール方法がわからない場合は、公式ドキュメントにアクセスしてください。 インストールが完了したら、コマンドプロンプトからexpoを使用して新しいReactNativeプロジェクトを初期化します。
expo init navigation-project
基本設定をどのようにするかを選択するためのいくつかのオプションが表示されます。
この場合、最初のオプションを選択して、プロジェクトを空白のドキュメントとして設定しましょう。 ここで、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での最終結果は次のようになります。
フォルダ構造
最初からフォルダ構造を作成して、作業を進めていくときに簡単に操作できるようにします。
最初に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ライブラリから必要なもの、つまりView
、 Text
、 Button
、 TextInput
をインポートしました。 次に、機能コンポーネントWelcomeScreen
を作成しました。
React NativeからStyleSheet
をインポートし、それを使用してヘッダーと<TextInput />
のスタイルを定義したことに気付くでしょう。
最後に、コードの下部にあるWelcomeScreen
コンポーネントをエクスポートします。
これでuseState
フックを使用して入力の値を格納し、入力フィールドで変更が発生するたびに状態を更新することで、このコンポーネントを期待どおりに機能させましょう。 また、関数を保持するために後で必要になるため、ReactからuseCallback
フックをインポートします。
まず、 WelcomeScreen
コンポーネントを使用している間に、ReactからuseState
とuseCallback
をインポートする必要があります。
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()
関数です。
理想的には、ユーザーはすでにアカウントを作成している必要があり、ログインには、ユーザーが存在することを確認してからトークンをユーザーに割り当てるための何らかのバックエンドロジックが含まれます。 この場合、バックエンドを使用していないため、正しいユーザーログインの詳細を保持するオブジェクトを作成し、ユーザーが入力した値が、 email
とpassword
のログインオブジェクトからの固定値と一致する場合にのみユーザーを認証します。作成。
これを行うために必要なコードは次のとおりです。
... 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コンポーネントの構築が完了したので、先に進んで、グローバル状態を管理するための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;
上記のコードブロックで、私たちが行ったことは次のとおりです。
userToken
とisLoading
の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()
からNavigator
とScreen
を分解しました。 - 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.jsとpostAuthNavigator.jsの唯一の違いは、レンダリングされる画面です。 最初のものはWelcomeScreen
を取りますが、 HomeScreen
はHomeScreenを取ります。
AppNavigator.jsを作成するには、いくつかのものを作成する必要があります。
AppNavigator.jsは、ユーザーがアクセスできるルートを切り替えて確認する場所であるため、これを正しく機能させるには、いくつかの画面を配置する必要があります。最初に作成する必要があるものの概要を説明します。
- TransitionScreen.js
アプリがマウントするナビゲーションを決定している間、トランジション画面を表示する必要があります。 通常、トランジション画面は、アプリ用に選択された読み込みスピナーまたはその他のカスタムアニメーションになりますが、この場合、基本的な<Text/>
タグを使用してloading…
。 -
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
の場合、userToken
がnull
のままであることを意味します。 -
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
上記のコードブロックで、私たちが行ったことの概要を次に示します。
- スタックナビゲーターを作成し、そこから
Navigator
とScreen
を分解しました。 -
isLoading
からuserToken
とAuthContext
をインポートしました AuthState
がマウントされると、useEffecct
フックでcheckAuthenticationStatus()
が呼び出されます。if
ステートメントを使用してisLoading
がtrue
かどうかを確認しますtrue
の場合、checkAuthenticationStatus()
関数がまだ完了していないため、返される画面は前に作成した<TransitionScreen />
です。-
checkAuthenticationStatus()
が完了すると、isLoading
がfalse
に設定され、メインのナビゲーションコンポーネントが返されます。 -
NavigationContainer
は@react-navigation/native
からインポートされました。 メインのトップレベルナビゲーターで1回だけ使用されます。 preAuthNavigator.jsまたはpostAuthNavigator.jsではこれを使用していないことに注意してください。 -
AppNavigator()
では、スタックナビゲーターを作成します。 Context APIから取得したuserToken
がnull
の場合、PreAuthNavigator
をマウントします。その値が他の値である場合(つまり、AsyncStorage.getItem()
のcheckAuthenticationStatus()
が実際の値を返した場合)、PostAuthNavigator
をマウントします。 条件付きレンダリングは、三項演算子を使用して行われます。
これで、 AppNavigator.jsを設定しました。 次に、 AppNavigator
をApp.jsファイルに渡す必要があります。
AppNavigator
をApp.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.jsでuserSignout()
関数を呼び出す必要があります。
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
のユーザートークンがクリアされます。
出来上がり! プロセス全体が終了しました。
ログイン後に戻るボタンを押すと、次のようになります。
ログアウト後に戻るボタンを押すと、次のようになります。
ナビゲーションスタックの切り替えでこのパターンを使用すると、いくつかの異なる動作が見られます。
- ログイン後に別のルートに移動するために
navigation.navigate()
またはnavigation.push()
を使用する必要がある場所がなかったことに気付くでしょう。 状態がユーザートークンで更新されると、レンダリングされるナビゲーションスタックは自動的に変更されます。 - ログインに成功した後にデバイスの戻るボタンを押しても、ログインページに戻ることはできません。代わりに、アプリが完全に閉じます。 ユーザーがアプリからログアウトする場合を除いて、ユーザーがログインページに戻れないようにするため、この動作は重要です。 同じことがログアウトにも当てはまります。ユーザーがログアウトすると、戻るボタンを使用して
HomeScreen
画面画面に戻ることはできませんが、代わりにアプリが閉じます。
結論
多くのアプリでは、保護されたコンテンツにアクセスしようとしている人が情報にアクセスする権利を持っていることを確認するため、認証は最も重要な部分の1つです。 それを正しく行う方法を学ぶことは、アプリケーションを優れた、直感的で、使いやすく/ナビゲートするための重要なステップです。
このコードに基づいて、追加を検討する可能性のあるものをいくつか示します。
- 入力フィールドを検証するためのフォーム検証。 FormikとYupを使用したReactNativeフォームの検証を確認してください。
- Gmail、Github、Facebook、Twitter、またはカスタムインターフェースと認証を統合するためのFirebase認証。 ReactNativeFirebaseをチェックしてください。
- 設計者向けのコード概念:認証と承認。
また、認証、セキュリティ、およびそれを正しく行う方法についてより多くのことを教えてくれる、私が見つけたいくつかの重要なリソースもあります。
資力
- React Native:ユーザー認証フローの説明
- 10Reactセキュリティのベストプラクティス
- 次の違反を防ぐことができる認証方法
- ここでアプリケーションのライブビルド/プレビューを表示します。
- GitHubでプロジェクトを表示します。