การจัดการการติดตั้งและการยกเลิกการต่อเชื่อมเส้นทางการนำทางใน React Native
เผยแพร่แล้ว: 2022-03-10ในบทความนี้ เราจะพูดถึงการ ติดตั้งและยกเลิกการต่อเชื่อมเส้นทางการนำทาง ใน React Native ลักษณะการทำงานที่คาดหวังของแอปของคุณคือเมื่อตรงตามเงื่อนไขการตรวจสอบสิทธิ์แล้ว เส้นทางการนำทางชุดใหม่จะพร้อมใช้งานสำหรับผู้ใช้ที่ลงชื่อเข้าใช้เท่านั้น ในขณะที่หน้าจออื่นๆ ที่แสดงก่อนการตรวจสอบสิทธิ์จะถูกลบออกและไม่สามารถย้อนกลับได้เว้นแต่ ผู้ใช้ออกจากระบบแอปพลิเคชัน
เพื่อความปลอดภัยในแอปของคุณ เส้นทางที่มีการป้องกันจะให้คุณแสดงเฉพาะข้อมูล/เนื้อหาบางอย่างในแอปของคุณต่อผู้ใช้บางราย ในขณะที่จำกัดการเข้าถึงจากบุคคลที่ไม่ได้รับอนุญาต
เราจะทำงานร่วมกับ Expo สำหรับโปรเจ็กต์นี้ เพราะมันจะช่วยให้เราโฟกัสที่ปัญหาในมือ แทนที่จะต้องกังวลกับการตั้งค่าจำนวนมาก คุณสามารถทำตามขั้นตอนเดียวกันในบทความนี้สำหรับแอปพลิเคชัน React Native เปล่า
คุณต้องมีความคุ้นเคยกับ JavaScript และ React Native เพื่อทำตามบทช่วยสอนนี้ ต่อไปนี้คือสิ่งสำคัญบางประการที่คุณน่าจะคุ้นเคยอยู่แล้ว:
- ส่วนประกอบที่กำหนดเองใน React Native (วิธีสร้างส่วนประกอบ รับ ส่งผ่าน และใช้อุปกรณ์ประกอบฉากในส่วนประกอบ) อ่านเพิ่มเติม.
- ตอบสนองการนำทาง อ่านเพิ่มเติม.
- Stack Navigator ใน React Native อ่านเพิ่มเติม.
- ความรู้พื้นฐานเกี่ยวกับส่วนประกอบ React Native Core (
<View/>
,<Text/>
ฯลฯ) อ่านเพิ่มเติม. - ตอบสนอง Native
AsyncStorage
อ่านเพิ่มเติม. - บริบท API อ่านเพิ่มเติม.
การตั้งค่าโปรเจ็กต์และการตรวจสอบฐาน
หากคุณเพิ่งเริ่มใช้งานงานมหกรรมและไม่ทราบวิธีการติดตั้งงานเอ็กซ์โป โปรดไปที่เอกสารประกอบอย่างเป็นทางการ เมื่อการติดตั้งเสร็จสิ้น ให้เริ่มต้นโครงการ React Native ใหม่ด้วย expo จากพรอมต์คำสั่งของเรา:
expo init navigation-project
คุณจะเห็นตัวเลือกบางอย่างเพื่อเลือกวิธีที่คุณต้องการให้การตั้งค่าพื้นฐานเป็น:
ในกรณีของเรา ให้เลือกตัวเลือกแรกเพื่อตั้งค่าโครงการของเราเป็นเอกสารเปล่า ตอนนี้ ให้รอจนกว่าการติดตั้งการพึ่งพา 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 navigation) - @react-navigation/native
นี่คือการพึ่งพาการนำทาง 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:
โครงสร้างโฟลเดอร์
ให้เราสร้างโครงสร้างโฟลเดอร์ของเราตั้งแต่เริ่มต้น เพื่อให้เราทำงานกับมันได้ง่ายขึ้นในขณะที่ดำเนินการต่อไป:
เราต้องการสองโฟลเดอร์ก่อน:
- บริบท
โฟลเดอร์นี้จะเก็บบริบทสำหรับแอปพลิเคชันทั้งหมดของเรา เนื่องจากเราจะทำงานร่วมกับ Context API สำหรับการจัดการสถานะทั่วโลก - มุมมอง
โฟลเดอร์นี้จะเก็บทั้งโฟลเดอร์การนำทางและมุมมองสำหรับหน้าจอต่างๆ
ไปข้างหน้าและสร้างสองโฟลเดอร์ในไดเรกทอรีโครงการของคุณ
ภายในโฟลเดอร์บริบท ให้สร้างโฟลเดอร์ชื่อ authContext และสร้างสองไฟล์ภายในโฟลเดอร์ authContext :
- AuthContext.js ,
- AuthState.js
เราจะต้องใช้ไฟล์เหล่านี้เมื่อเราเริ่มทำงานกับ Context API
ไปที่โฟลเดอร์ มุมมอง ที่เราสร้างและสร้างอีกสองโฟลเดอร์ภายในนั้น ได้แก่:
- การนำทาง ,
- หน้าจอ
ตอนนี้ เรายังไม่เสร็จสิ้น ภายในโฟลเดอร์ หน้าจอ ให้สร้างอีกสองโฟลเดอร์นี้:
- postAuthScreens ,
- preAuthScreens
หากคุณปฏิบัติตามการตั้งค่าโฟลเดอร์อย่างถูกต้อง โครงสร้างโฟลเดอร์ของคุณควรมีลักษณะดังนี้:
การสร้างหน้าจอแรกของเรา
ตอนนี้ มาสร้างหน้าจอแรกของเราและเรียกมันว่า welcomeScreen.js ภายในโฟลเดอร์ preAuthScreens
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
คุณจะสังเกตเห็นว่าเรานำเข้า StyleSheet
จาก React Native และใช้เพื่อกำหนดสไตล์สำหรับส่วนหัวของเราและ <TextInput />
ของเราด้วย
สุดท้าย เราส่งออกองค์ประกอบ WelcomeScreen
ที่ด้านล่างของโค้ด
เมื่อเราทำสิ่งนี้เสร็จแล้ว ให้ส่วนประกอบนี้ทำงานตามที่คาดไว้โดยใช้ hook ของ useState
เพื่อเก็บค่าของอินพุตและอัปเดตสถานะทุกครั้งที่มีการเปลี่ยนแปลงเกิดขึ้นในช่องใส่ นอกจากนี้เรายังจะนำเข้า useCallback
hook จาก React เนื่องจากเราต้องการใช้ในภายหลังเพื่อคงฟังก์ชันไว้
อันดับแรก ในขณะที่เรายังอยู่ในองค์ประกอบ WelcomeScreen
เราต้องนำเข้า useState
และ useCallback
จาก React
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
ซึ่งยอมรับสองอาร์กิวเมนต์:-
value
ปัจจุบันมาจากตัวจัดการonChangeText
- ตัวกำหนดสถานะที่ควรได้รับการอัปเดต (สำหรับช่องป้อนข้อมูลแรกเราผ่าน
setEmail
และช่องที่สองที่เราส่งsetPassword
- สุดท้าย เราเขียนฟังก์ชัน
onInputChange
ของเรา และฟังก์ชันของเราทำสิ่งเดียวเท่านั้น: อัปเดตสถานะที่เกี่ยวข้องด้วยค่าใหม่
-
สิ่งต่อไปที่เราต้องดำเนินการคือ 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 ( ... ) } ...
สิ่งแรกที่คุณจะสังเกตเห็นในโค้ดด้านบนคือเราได้กำหนด correctAuthenticationDetails
(ซึ่งเป็นอ็อบเจ็กต์ที่มีรายละเอียดการเข้าสู่ระบบที่ถูกต้องซึ่งเราคาดหวังให้ผู้ใช้จัดหา) นอกองค์ประกอบการทำงาน WelcomeScreen()
ต่อไป เราเขียนเนื้อหาของ 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 เสร็จแล้ว มาเริ่มการทำงานกับ Context API เพื่อจัดการสถานะส่วนกลางของเรากัน
ทำไมต้อง Context API
เมื่อใช้ Context API เราไม่จำเป็นต้องติดตั้งไลบรารี่เพิ่มเติมใน ReactJS ทำให้การตั้งค่าไม่ยุ่งยาก และเป็นหนึ่งในวิธีที่นิยมที่สุดในการจัดการสถานะส่วนกลางใน ReactJS สำหรับการจัดการสถานะน้ำหนักเบาเป็นทางเลือกที่ดี
การสร้างบริบทของเรา
หากคุณจำได้ เราได้สร้างโฟลเดอร์ บริบท ไว้ก่อนหน้านี้ และสร้างโฟลเดอร์ย่อยภายในที่เรียกว่า authContext
ตอนนี้ ให้ไปที่ไฟล์ AuthContext.js ในโฟลเดอร์ authContext และสร้างบริบทของเรา:
บริบท > 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 เก็บตรรกะ Context API ของเราและค่าสถานะไว้ ฟังก์ชันที่เขียนที่นี่สามารถเรียกได้จากทุกที่ในแอปของเรา และเมื่ออัปเดตค่าในสถานะ ฟังก์ชันจะอัปเดตทั่วโลกด้วย
ขั้นแรก ให้นำเข้าทั้งหมดที่เราต้องการในไฟล์นี้:
บริบท > AuthContext > AuthState.js
import React, { useState } from 'react'; import AuthContext from './AuthContext'; import AsyncStorage from '@react-native-community/async-storage';
เรานำเข้า useState()
จาก ReactJS เพื่อเก็บสถานะของเรา เรานำเข้าไฟล์ AuthContext ที่เราสร้างขึ้นด้านบนเพราะนี่คือจุดเริ่มต้นของบริบทที่ว่างเปล่าสำหรับการตรวจสอบสิทธิ์ของเรา และเราจำเป็นต้องใช้มันดังที่คุณเห็นในภายหลังในขณะที่เราดำเนินการ ในที่สุด เราก็นำเข้าแพ็คเกจ AsyncStorage
(คล้ายกับ localStorage สำหรับเว็บ)
AsyncStorage
เป็น React Native API ที่ให้คุณคงข้อมูลออฟไลน์บนอุปกรณ์ในแอปพลิเคชัน React Native
... 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
สถานะuserToken
จะถูกใช้เพื่อจัดเก็บโทเค็นที่บันทึกไว้ในAsyncStorage
ในขณะที่สถานะisLoading
จะถูกใช้เพื่อติดตามสถานะการโหลด (ในขั้นต้นจะถูกตั้งค่าtrue
) เราจะหาข้อมูลเพิ่มเติมเกี่ยวกับการใช้สองสถานะนี้เมื่อเราดำเนินการต่อไปต่อไป เราเขียน
onAuthentication()
ฟังก์ชันนี้เป็นฟังก์ชันasync
ที่เรียกใช้เมื่อมีการคลิกปุ่มเข้าสู่ระบบจากไฟล์welcomeScreen.jsx
ฟังก์ชันนี้จะถูกเรียกก็ต่อเมื่ออีเมลและรหัสผ่านที่ผู้ใช้ระบุตรงกับออบเจ็กต์รายละเอียดผู้ใช้ที่ถูกต้องที่เราให้ไว้ โดยปกติสิ่งที่เกิดขึ้นระหว่างการตรวจสอบความถูกต้องคือโทเค็นจะถูกสร้างขึ้นสำหรับผู้ใช้หลังจากที่ผู้ใช้ได้รับการตรวจสอบสิทธิ์ในแบ็กเอนด์โดยใช้แพ็คเกจเช่น JWT และโทเค็นนี้จะถูกส่งไปยังส่วนหน้า เนื่องจากเราไม่ได้กล่าวถึงทั้งหมดสำหรับบทช่วยสอนนี้ เราจึงสร้างโทเค็นแบบคงที่และเก็บไว้ในตัวแปรที่เรียกว่าUSER_TOKEN
ต่อไป เราใช้คำสำคัญ
await
เพื่อตั้งค่าโทเค็นผู้ใช้ของเราเป็น AsyncStorage ด้วยชื่อuser-token
คำสั่งconsole.warn()
ใช้เพื่อตรวจสอบว่าทุกอย่างถูกต้องแล้ว คุณสามารถถอดออกได้ทุกเมื่อที่ต้องการสุดท้าย เราส่งฟังก์ชัน
onAuthenticated
เป็นค่าภายใน<AuthContext.Provider>
เพื่อให้เราสามารถเข้าถึงและเรียกใช้ฟังก์ชันได้จากทุกที่ในแอปของเรา
หน้าจอ > การตรวจสอบสิทธิ์ล่วงหน้า > welcomeScreen.js
ขั้นแรก นำเข้า useContext
จาก ReactJS และนำเข้า 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 ( ... ) } ...
ในบล็อกโค้ดด้านบน เราได้ทำลายโครงสร้างฟังก์ชัน 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 ซึ่งควรจะปรากฏขึ้นหลังจากการตรวจสอบสิทธิ์สำเร็จเท่านั้น
ไปที่: screens > 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
เมื่อคุณสร้างไฟล์ทั้งสามนี้แล้ว ให้ไปที่ไฟล์ 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;
ในไฟล์ด้านบน นี่คือสิ่งที่เราทำ:
- เรานำเข้า
createStackNavigator
จาก@react-navigation/stack
ที่เราใช้สำหรับการนำทางสแต็กของเราcreateStackNavigator
ให้วิธีสำหรับแอปของคุณในการเปลี่ยนระหว่างหน้าจอโดยวางหน้าจอใหม่แต่ละหน้าจอไว้บนสแต็ก ตามค่าเริ่มต้น Stack Navigator จะได้รับการกำหนดค่าให้มีรูปลักษณ์และความรู้สึกของ iOS และ Android ที่คุ้นเคย: หน้าจอใหม่จะเลื่อนเข้ามาจากด้านขวาบน iOS และค่อยๆ จางลงจากด้านล่างของ Android คลิกที่นี่ หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ stack navigator ใน React Native - เราทำลายโครงสร้าง
Navigator
และScreen
จากcreateStackNavigator()
- ในคำสั่ง 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
แต่ postAuthNavigator.js จะใช้ 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
เพื่อตั้งค่าที่ส่งคืนจากAsyncStorage
เป็นuserToken
ใหม่ของเรา หากค่าที่ส่งคืนเป็นnull
หมายความว่าuserToken
ของเรายังคงเป็นnull
- หลังจากบล็อก
try{}…catch(){}
เราตั้งค่าisLoading
เป็น false เนื่องจากฟังก์ชันตรวจสอบสถานะการรับรองความถูกต้องเสร็จสมบูรณ์ เราต้องการค่าของisLoading
เพื่อทราบว่าเราควรยังคงแสดงTransitionScreen
อยู่หรือไม่ ควรพิจารณาตั้งค่าข้อผิดพลาดหากมีข้อผิดพลาดในการดึงโทเค็น เพื่อให้เราสามารถแสดงปุ่ม "ลองใหม่" หรือ "ลองอีกครั้ง" ให้ผู้ใช้เห็นเมื่อพบข้อผิดพลาด - เมื่อใดก็ตาม
AuthState
ติดตั้ง เราต้องการตรวจสอบสถานะการรับรองความถูกต้อง ดังนั้นเราจึงใช้useEffect()
ReactJS เพื่อทำสิ่งนี้ เราเรียกcheckAuthenticationStatus()
ภายในuseEffect()
hook และตั้งค่าisLoading
false
เมื่อเสร็จสิ้น - สุดท้าย เราเพิ่มสถานะของเราลงในค่า
<AuthContext.Provider/>
เพื่อให้เราสามารถเข้าถึงได้จากทุกที่ในแอปของเราที่ครอบคลุมโดย Context API
ตอนนี้เรามีฟังก์ชันของเราแล้ว ก็ถึงเวลาที่จะกลับไปที่ AppNavigator.js และเขียนโค้ดสำหรับติดตั้ง stack navigator โดยเฉพาะตามสถานะการตรวจสอบสิทธิ์:
การนำทาง > 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
จากมัน - เรานำเข้า
userToken
และisLoading
จากAuthContext
. ของเรา - เมื่อ
AuthState
เมานต์ จะมีการเรียกcheckAuthenticationStatus()
ในเบ็ดuseEffecct
ที่นั่น เราใช้คำสั่งif
เพื่อตรวจสอบว่าisLoading
เป็นtrue
หรือไม่ หากเป็นtrue
หน้าจอที่เราส่งคืนคือ<TransitionScreen />
ที่เราสร้างขึ้นก่อนหน้านี้เนื่องจากcheckAuthenticationStatus()
ยังไม่สมบูรณ์ - เมื่อ
checkAuthenticationStatus()
ของเราเสร็จสมบูรณ์isLoading
จะถูกตั้งค่าfalse
และเราส่งคืนส่วนประกอบการนำทางหลักของเรา -
NavigationContainer
ถูกนำเข้าจาก@react-navigation/native
ใช้เพียงครั้งเดียวในเนวิเกเตอร์หลักระดับบนสุด โปรดสังเกตว่าเราไม่ได้ใช้งานสิ่งนี้ใน preAuthNavigator.js หรือ postAuthNavigator.js - ใน
AppNavigator()
ของเรา เรายังคงสร้าง stack navigator หากuserToken
ได้รับจาก Context API ของเราเป็นnull
เราจะเมานPreAuthNavigator
หากค่านั้นเป็นอย่างอื่น (หมายความว่าAsyncStorage.getItem()
ในcheckAuthenticationStatus()
คืนค่าจริง) จากนั้นเราจะเมานต์PostAuthNavigator
การเรนเดอร์แบบมีเงื่อนไขของเราทำได้โดยใช้ตัวดำเนินการ ternary
ตอนนี้เราได้ตั้งค่า 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()
เป็นฟังก์ชันแบบอะซิงโครนัสที่จะลบ user-token
ออกจาก AsyncStorage
ของเรา
ตอนนี้เราต้องเรียกใช้ userSignout()
ใน HomeScreen.js ของเราทุกครั้งที่คลิกปุ่มออกจากระบบ
ไปที่ HomeScreen.js ของเราและใช้ userSignout()
จาก AuthContext
ของเรา
หน้าจอ > 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> ) } ...
ในบล็อกโค้ดด้านบนเรานำเข้า useContext
hook จาก ReactJS จากนั้นเรานำเข้า AuthContext ของเรา ต่อไป เราทำลายโครงสร้างฟังก์ชัน userSignout
จาก AuthContext
ของเรา และฟังก์ชัน userSignout()
นี้ถูกเรียกใช้ใน onLogout()
ของเรา
ตอนนี้เมื่อใดก็ตามที่คลิกปุ่มออกจากระบบ โทเค็นผู้ใช้ใน AsyncStorage
ของเราจะถูกล้าง
โว้ว! กระบวนการทั้งหมดของเราเสร็จสิ้น
นี่คือสิ่งที่จะเกิดขึ้นเมื่อคุณกดปุ่มย้อนกลับหลังจากที่คุณเข้าสู่ระบบ:
นี่คือสิ่งที่จะเกิดขึ้นเมื่อคุณกดปุ่มย้อนกลับหลังจากออกจากระบบ:
ต่อไปนี้คือพฤติกรรมบางอย่างที่เราสังเกตเห็นเมื่อใช้รูปแบบนี้ในการสลับสแต็กการนำทางของเรา:
- คุณจะสังเกตเห็นว่าไม่มีที่ไหนที่เราจำเป็นต้องใช้
navigation.navigate()
หรือnavigation.push()
เพื่อไปยังเส้นทางอื่นหลังจากเข้าสู่ระบบ เมื่อสถานะของเราได้รับการอัปเดตด้วยโทเค็นผู้ใช้ การแสดงสแต็กการนำทางจะเปลี่ยนไปโดยอัตโนมัติ - การกดปุ่มย้อนกลับบนอุปกรณ์ของคุณหลังจากเข้าสู่ระบบสำเร็จแล้วจะไม่สามารถนำคุณกลับไปที่หน้าการเข้าสู่ระบบได้ แต่จะเป็นการปิดแอปทั้งหมดแทน ลักษณะการทำงานนี้มีความสำคัญเนื่องจากคุณไม่ต้องการให้ผู้ใช้สามารถกลับไปที่หน้าเข้าสู่ระบบได้ เว้นแต่จะออกจากระบบแอป เช่นเดียวกับการออกจากระบบ เมื่อผู้ใช้ออกจากระบบแล้ว จะไม่สามารถใช้ปุ่มย้อนกลับเพื่อกลับไปยัง
HomeScreen
จอหลักได้ แต่แอปจะปิดลงแทน
บทสรุป
ในหลาย ๆ แอพ การตรวจสอบสิทธิ์เป็นส่วนที่สำคัญที่สุดเพราะเป็นการยืนยันว่าบุคคลที่พยายามเข้าถึงเนื้อหาที่ได้รับการคุ้มครองมีสิทธิ์ในการเข้าถึงข้อมูล การเรียนรู้วิธีทำให้ถูกต้องเป็นขั้นตอนสำคัญในการสร้างแอปพลิเคชัน/การนำทางที่ยอดเยี่ยม ใช้งานง่าย และใช้งานง่าย
ต่อจากโค้ดนี้ ต่อไปนี้คือบางสิ่งที่คุณอาจพิจารณาเพิ่ม:
- การตรวจสอบแบบฟอร์มสำหรับตรวจสอบช่องป้อนข้อมูล ตรวจสอบการตรวจสอบความถูกต้องของแบบฟอร์ม React Native ด้วย Formik และ Yup
- การตรวจสอบสิทธิ์ Firebase สำหรับการรวมการตรวจสอบสิทธิ์กับ Gmail, Github, Facebook, Twitter หรืออินเทอร์เฟซที่กำหนดเองของคุณ ลองใช้ React Native Firebase
- แนวคิดโค้ดสำหรับนักออกแบบ: การพิสูจน์ตัวตนและการอนุญาต
ต่อไปนี้คือแหล่งข้อมูลสำคัญบางส่วนที่ฉันพบว่าจะช่วยให้คุณเข้าใจมากขึ้นเกี่ยวกับการรับรองความถูกต้อง ความปลอดภัย และวิธีดำเนินการอย่างถูกต้อง:
ทรัพยากร
- React Native: อธิบายขั้นตอนการตรวจสอบผู้ใช้
- 10 React Security แนวทางปฏิบัติที่ดีที่สุด
- วิธีการตรวจสอบสิทธิ์ที่สามารถป้องกันการละเมิดครั้งต่อไปได้
- ดูบิลด์ / ดูตัวอย่างแอปพลิเคชันของเราที่นี่;
- ดูโครงการบน GitHub