React Native에서 탐색 경로의 마운트 및 마운트 해제 처리

게시 됨: 2022-03-10
빠른 요약 ↬ 종종 사전 및 사후 사용자 인증을 위해 두 가지 다른 탐색 스택 세트가 필요합니다. 일반적으로 더 많은 콘텐츠를 보려면 어떤 방식으로든 인증을 받아야 합니다. React Native에서 충족된 조건에 따라 탐색 스택을 마운트 및 마운트 해제하는 방법을 살펴보겠습니다.

이 기사에서는 React Native에서 탐색 경로를 마운트 및 마운트 해제하는 방법을 살펴보겠습니다. 앱에서 예상되는 동작은 인증 조건이 충족되면 로그인한 사용자만 새로운 탐색 경로 집합을 사용할 수 있는 반면 인증 전에 표시된 다른 화면은 제거되고 사용자가 애플리케이션에서 로그아웃합니다.

앱의 보안을 위해 보호된 경로는 앱의 특정 정보/콘텐츠를 특정 사용자에게만 표시하는 방법을 제공하는 동시에 승인되지 않은 사람의 액세스를 제한합니다.

많은 설정에 대해 걱정하는 대신 당면한 문제에 집중하는 데 도움이 될 것이기 때문에 이 프로젝트를 위해 Expo와 협력할 것입니다. 이 기사의 똑같은 단계를 베어 React Native 애플리케이션에 대해 따를 수 있습니다.

이 튜토리얼을 진행하려면 JavaScript 및 React Native 에 대해 어느 정도 익숙해야 합니다. 다음은 이미 알고 있어야 하는 몇 가지 중요한 사항입니다.

  • React Native의 사용자 지정 구성 요소(구성 요소를 만들고 구성 요소에서 props를 수신, 전달 및 사용하는 방법). 더 읽어보세요.
  • 반응 탐색. 더 읽어보세요.
  • React Native의 스택 내비게이터. 더 읽어보세요.
  • React Native Core 구성 요소( <View/> , <Text/> 등)에 대한 기본 지식. 더 읽어보세요.
  • 네이티브 AsyncStorage 에 반응합니다. 더 읽어보세요.
  • 컨텍스트 API. 더 읽어보세요.

프로젝트 설정 및 기본 인증

엑스포를 처음 사용하고 엑스포를 설치하는 방법을 모르는 경우 공식 문서를 방문하세요. 설치가 완료되면 명령 프롬프트에서 expo를 사용하여 새 React Native 프로젝트를 초기화합니다.

 expo init navigation-project

기본 설정 방법을 선택할 수 있는 몇 가지 옵션이 표시됩니다.

React Native 프로젝트의 기본 설정
(큰 미리보기)

이 경우 첫 번째 옵션을 선택하여 프로젝트를 빈 문서로 설정하겠습니다. 이제 JavaScript 종속성 설치가 완료될 때까지 기다리십시오.

앱이 설정되면 디렉터리를 새 프로젝트 디렉터리로 변경하고 즐겨 사용하는 코드 편집기에서 열 수 있습니다. AsyncStorage 및 탐색 라이브러리에 사용할 라이브러리를 설치해야 합니다. 터미널의 폴더 디렉토리 안에 위의 명령을 붙여넣고 템플릿을 선택( blank 이 작동함)하여 프로젝트 종속성을 설치합니다.

이러한 종속성이 각각 무엇을 위한 것인지 살펴보겠습니다.

  • @react-native-community/async-storage
    웹의 localStorage와 마찬가지로 기기의 데이터를 키-값 쌍으로 유지하기 위한 React Native API입니다.
  • @react-native-community/masked-view, react-native-screens, react-native-gesture-handle
    이러한 종속성은 대부분의 네비게이터가 앱에서 탐색 구조를 생성하는 데 사용하는 핵심 유틸리티입니다. (React Native 탐색 시작하기에서 자세히 읽어보세요.)
  • @react-navigation/네이티브
    이것은 React Native 탐색에 대한 종속성입니다.
  • @react-navigation/stack
    이것은 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

응용 프로그램을 시작하려면 터미널의 앱 디렉터리에서 expo start 을 사용합니다. 앱이 시작되면 휴대 전화에서 엑스포 앱을 사용하여 바코드를 스캔하고 응용 프로그램을 볼 수 있습니다. Android 에뮬레이터/IOS 시뮬레이터가 있는 경우 엑스포 개발자 도구에서 앱을 열 수 있습니다. 엑스포 응용 프로그램을 시작할 때 브라우저에서 열립니다. 이 기사의 이미지 예에서는 Genymotions를 사용하여 결과를 볼 것입니다. Genymotions에서 최종 결과는 다음과 같습니다.

Genymotions의 최종 결과
(큰 미리보기)

폴더 구조

진행하면서 더 쉽게 작업할 수 있도록 처음부터 폴더 구조를 만들어 보겠습니다.

먼저 두 개의 폴더가 필요합니다.

  • 문맥
    이 폴더는 전역 상태 관리를 위해 Context API로 작업할 것이기 때문에 전체 애플리케이션에 대한 컨텍스트를 보유합니다.
  • 견해
    이 폴더에는 탐색 폴더와 다른 화면에 대한 보기가 모두 포함됩니다.

계속해서 프로젝트 디렉토리에 두 개의 폴더를 만드십시오.

컨텍스트 폴더 안에 authContext 라는 폴더를 만들고 authContext 폴더 안에 두 개의 파일을 만듭니다.

  • AuthContext.js ,
  • 인증 상태.js .

Context API 작업을 시작할 때 이 파일이 필요합니다.

이제 우리가 만든 보기 폴더로 이동하여 그 안에 두 개의 폴더를 더 만듭니다.

  • 탐색 ,
  • 스크린 .

이제 화면 폴더 안에 다음 두 개의 폴더를 더 만듭니다.

  • postAuth스크린 ,
  • 사전 인증 화면 .

폴더 설정을 올바르게 따랐다면 현재 폴더 구조가 다음과 같아야 합니다.

폴더 구조
(큰 미리보기)
점프 후 더! 아래에서 계속 읽기 ↓

첫 화면 만들기

이제 첫 번째 화면을 만들고 preAuthScreen 폴더 내에서 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에서 useStateuseCallback 을 가져와야 합니다.

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

이제 WelcomeScreen 기능 구성 요소 내부에서 이메일과 비밀번호에 대한 두 가지 상태를 각각 생성해 보겠습니다.

 ... 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 핸들러를 추가했습니다. 새 값이 입력 필드에서 입력되거나 삭제될 때마다 실행됩니다.
  • 두 개의 인수를 허용하는 onInputChange 함수를 호출했습니다.
    • 현재 valueonChangeText 핸들러에서 제공합니다.
    • 업데이트되어야 하는 상태의 설정자(첫 번째 입력 필드에 대해 setEmail 을 전달하고 두 번째 입력 필드에 대해 setPassword 를 전달합니다.
    • 마지막으로 onInputChange 함수를 작성하고 이 함수는 한 가지만 수행합니다. 각 상태를 새 값으로 업데이트합니다.

다음으로 작업해야 할 것은 양식 제출 버튼을 클릭할 때마다 호출되는 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 구성 요소 빌드를 완료했으므로 계속 진행하여 전역 상태를 관리하기 위한 Context API 작업을 시작하겠습니다.

컨텍스트 API가 필요한 이유

Context API를 사용하면 ReactJS에 추가 라이브러리를 설치할 필요가 없으며 설정하는 데 스트레스가 덜하고 ReactJS에서 전역 상태를 처리하는 가장 인기 있는 방법 중 하나입니다. 가벼운 상태 관리를 위해서는 좋은 선택입니다.

컨텍스트 만들기

회상하는 경우 이전에 컨텍스트 폴더를 만들고 그 안에 authContext 라는 하위 폴더를 만들었습니다.

이제 authContext 폴더의 AuthContext.js 파일로 이동하여 컨텍스트를 생성해 보겠습니다.

컨텍스트 > authContext > AuthContext.js

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

방금 생성한 AuthContextloading 상태 값과 userToken 상태 값을 보유합니다. 현재 위의 코드 블록에서 선언한 createContext 에서 기본값을 초기화하지 않았으므로 컨텍스트가 현재 undefined 입니다. 인증 컨텍스트 값의 예는 {loading: false, userToken: 'abcd} 수 있습니다.

AuthState.js 파일에는 Context 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 패키지를 가져옵니다(웹용 localStorage와 유사).

AsyncStorage 는 React Native 애플리케이션에서 장치를 통해 오프라인으로 데이터를 유지할 수 있는 React Native API입니다.

 ... 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 에 대해 두 가지 상태를 선언했습니다. userToken 상태는 AsyncStorage 에 저장된 토큰을 저장하는 데 사용되는 반면 isLoading 상태는 로드 상태를 추적하는 데 사용됩니다(초기에는 true 로 설정됨). 계속 진행하면서 이 두 상태의 사용에 대해 자세히 알아보겠습니다.

  • 다음으로 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 함수를 구조화한 다음 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 ,
  • 앱내비게이터.js .

이 세 개의 파일을 생성했으면 방금 생성한 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 을 취하는 동안 postAuthNavigator.js WelcomeScreen HomeScreen 을 취합니다.

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() 함수를 작성했습니다. 우리가 하는 일은 다음과 같습니다.

  • AsyncStorage 에서 토큰을 가져오기 위해 await 키워드를 사용했습니다. AsyncStorage 를 사용하면 제공된 토큰이 없으면 null 을 반환합니다. 초기 userToken 상태도 null 로 설정됩니다.
  • setUserToken을 사용하여 setUserToken 에서 반환된 값을 새 AsyncStorage 으로 userToken 합니다. 반환된 값이 null userTokennull 로 유지된다는 의미입니다.
  • try{}…catch(){} 블록 이후에는 인증 상태를 확인하는 함수가 완료 isLoading 을 false로 설정합니다. TransitionScreen 을 계속 표시해야 하는지 여부를 알기 위해서는 isLoading 값이 필요합니다. 오류가 발생했을 때 사용자에게 "다시 시도" 또는 "다시 시도" 버튼을 표시할 수 있도록 토큰 검색 오류가 있는 경우 오류 설정을 고려해 볼 가치가 있습니다.
  • AuthState 가 마운트될 때마다 인증 상태를 확인하기를 원하므로 useEffect() ReactJS 후크를 사용하여 이를 수행합니다. useEffect() 후크 내에서 checkAuthenticationStatus checkAuthenticationStatus() 함수를 호출하고 완료되면 isLoading 값을 false 로 설정합니다.
  • 마지막으로 <AuthContext.Provider/> 값에 상태를 추가하여 Context API가 적용되는 앱의 어디에서나 상태에 액세스할 수 있습니다.

이제 함수가 생겼으므로 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 을 구조화했습니다.
  • AuthContext에서 userTokenisLoading 을 가져 AuthContext .
  • AuthState 가 마운트되면 거기에 있는 useEffecct 후크에서 checkAuthenticationStatus() 가 호출됩니다. if 문을 사용하여 isLoadingtrue 인지 확인하고, true checkAuthenticationStatus() 함수가 아직 완료되지 않았기 때문에 이전에 생성한 <TransitionScreen /> 화면이 반환됩니다.
  • checkAuthenticationStatus() 가 완료되면 isLoadingfalse 로 설정되고 기본 탐색 구성 요소를 반환합니다.
  • NavigationContainer@react-navigation/native 에서 가져왔습니다. 메인 최상위 네비게이터에서 한 번만 사용됩니다. preAuthNavigator.js 또는 postAuthNavigator.js에서는 이것을 사용하지 않는다는 점에 유의하세요.
  • AppNavigator() 에서 여전히 스택 내비게이터를 생성합니다. Context API에서 userTokennull PreAuthNavigator 를 탑재하고, 그 값이 다른 값이면 AsyncStorage.getItem()checkAuthenticationStatus() 이 실제 값을 반환했음을 의미) PostAuthNavigator 를 탑재합니다. 조건부 렌더링은 삼항 연산자를 사용하여 수행됩니다.

이제 AppNavigator.js 를 설정했습니다. 다음으로 AppNavigatorApp.js 파일에 전달해야 합니다.

AppNavigatorApp.js 파일에 전달해 보겠습니다.

앱.js

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

이제 우리 앱이 현재 어떻게 생겼는지 봅시다.

로그인을 시도하는 동안 잘못된 자격 증명을 제공하면 다음과 같은 일이 발생합니다.

로그아웃 기능 추가

이 시점에서 인증 및 경로 선택 프로세스가 완료됩니다. 우리 앱에 남은 유일한 것은 로그아웃 기능을 추가하는 것입니다.

로그아웃 버튼은 HomeScreen.js 파일에 있습니다. 버튼의 onPress 속성에 onLogout() 함수를 전달했습니다. 지금은 함수에 간단한 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() 을 사용하겠습니다.

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

위의 코드 블록에서 ReactJS에서 useContext 후크를 가져온 다음 AuthContext를 가져왔습니다. 다음으로 AuthContext에서 userSignout 함수를 AuthContext 했으며 이 userSignout() 함수는 onLogout() () 함수에서 호출됩니다.

이제 로그아웃 버튼을 클릭할 때마다 AsyncStorage 의 사용자 토큰이 지워집니다.

짜잔! 우리의 모든 과정이 끝났습니다.

로그인한 후 뒤로 버튼을 누르면 다음과 같이 됩니다.

앱 로그인 후 뒤로가기 버튼을 누르세요.

로그아웃 후 뒤로 버튼을 누르면 다음과 같이 됩니다.

앱에서 로그아웃한 후 뒤로 버튼을 누릅니다.

다음은 탐색 스택 전환에서 이 패턴을 사용할 때 발견한 몇 가지 다른 동작입니다.

  1. 로그인 후 다른 경로로 이동하기 위해 navigation.navigate() 또는 navigation.push() 를 사용할 필요가 없었음을 알 수 있습니다. 상태가 사용자 토큰으로 업데이트되면 렌더링된 탐색 스택이 자동으로 변경됩니다.
  2. 로그인에 성공한 후 기기의 뒤로 버튼을 누르면 로그인 페이지로 돌아갈 수 없으며 대신 앱이 완전히 닫힙니다. 이 동작은 사용자가 앱에서 로그아웃하는 경우를 제외하고는 로그인 페이지로 돌아갈 수 없도록 하기 때문에 중요합니다. 동일한 사항이 로그아웃에 적용됩니다. 사용자가 로그아웃하면 뒤로 버튼을 사용하여 HomeScreen 화면 화면으로 돌아갈 수 없지만 대신 앱이 닫힙니다.

결론

많은 앱에서 인증은 보호된 콘텐츠에 액세스하려는 사람이 정보에 액세스할 수 있는 권한이 있는지 확인하기 때문에 가장 중요한 부분 중 하나입니다. 올바르게 수행하는 방법을 배우는 것은 훌륭하고 직관적이며 사용/탐색하기 쉬운 애플리케이션을 구축하는 중요한 단계입니다.

이 코드를 기반으로 다음 몇 가지 사항을 추가할 수 있습니다.

  • 입력 필드 유효성 검사를 위한 양식 유효성 검사. Formik 및 Yup을 사용한 React Native 양식 유효성 검사를 확인하십시오.
  • Gmail, Github, Facebook, Twitter 또는 사용자 정의 인터페이스와의 인증 통합을 위한 Firebase 인증입니다. React Native Firebase를 확인하세요.
  • 디자이너를 위한 코드 개념: 인증 및 권한 부여.

다음은 인증, 보안 및 올바르게 수행하는 방법에 대해 자세히 알려줄 몇 가지 중요한 리소스입니다.

자원

  • React Native: 사용자 인증 흐름 설명
  • 10가지 React 보안 모범 사례
  • 다음 침해를 방지할 수 있는 인증 방법
  • 여기에서 애플리케이션의 실시간 빌드/미리보기를 확인하세요.
  • GitHub에서 프로젝트를 봅니다.