尝试使用React Navigation v5,所以我创建了一个登录注册表单,如果用户在使用AsyncStorage之前已登录,则将其带到仪表板。它工作正常,但我想知道如何改进代码结构。目前,我将所有组件放在堆栈导航器中,但是如果要添加更多屏幕,事情可能会变得混乱。另外,我将切换到钩子,但是对于是否以及如何应用useContext useMemo useEffect
感到困惑App.js文件
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import Login from './components/login';
import Signup from './components/signup';
import Dashboard from './components/dashboard';
import AuthLoading from './components/authLoading'
const Stack = createStackNavigator();
function MyStack() {
return (
<Stack.Navigator
initialRouteName="AuthLoading"
screenOptions={{
headerTitleAlign: 'center',
headerStyle: {
backgroundColor: '#3740FE',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}>
<Stack.Screen
name="AuthLoading"
component={AuthLoading}
options={
{title: 'AuthLoading'},
{headerLeft:null}
}/>
<Stack.Screen
name="Signup"
component={Signup}
options={{ title: 'Signup' }}
/>
<Stack.Screen
name="Login"
component={Login}
options={
{ title: 'Login' },
{ headerLeft: null }
}
/>
<Stack.Screen
name="Dashboard"
component={Dashboard}
options={
{ title: 'Dashboard' },
{ headerLeft: null }
}
/>
</Stack.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyStack />
</NavigationContainer>
);
}
authLoading.js文件
import React from 'react';
import { ActivityIndicator, StatusBar, StyleSheet, View, Text } from 'react-native';
import {AsyncStorage} from 'react-native'
export default class AuthLoadingScreen extends React.Component {
constructor(props) {
super(props);
this.checkUserToken();
}
async checkUserToken() {
const isLoggedIn = await AsyncStorage.getItem('isLoggedIn');
console.log(isLoggedIn)
// If User Token
if (isLoggedIn === '1') {
//AsyncStorage.setItem(isLoggedIn);
this.props.navigation.navigate('Dashboard');
}
else {
this.props.navigation.navigate('Login');
}
}
// Render any loading content that you like here
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>Checking Authentication</Text>
<ActivityIndicator />
<StatusBar barStyle="default" />
</View>
);
}
}
// Styles
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#CA3433',
justifyContent: 'center',
alignItems: 'center',
},
text: {
justifyContent: 'center',
color: '#fff',
fontSize: 18,
fontWeight: '500',
},
});
signup.js文件
import React, { Component } from 'react';
import { StyleSheet, Text, View, TextInput, Button, Alert, ActivityIndicator } from 'react-native';
import firebase from '../database/firebase';
export default class Signup extends Component {
constructor() {
super();
this.state = {
displayName: '',
email: '',
password: '',
isLoading: false
}
}
updateInputVal = (val, prop) => {
const state = this.state;
state[prop] = val;
this.setState(state);
}
registerUser = () => {
if (this.state.email === '' && this.state.password === '') {
Alert.alert('Enter details to signup!')
} else {
this.setState({
isLoading: true,
})
firebase
.auth()
.createUserWithEmailAndPassword(this.state.email, this.state.password)
.then((res) => {
res.user.updateProfile({
displayName: this.state.displayName
})
console.log('User registered successfully!')
this.setState({
isLoading: false,
displayName: '',
email: '',
password: ''
})
this.props.navigation.navigate('Login')
})
.catch(error => this.setState({
isLoading: false,
errorMessage: error.message
}))
}
}
render() {
if (this.state.isLoading) {
return (
<View style={styles.preloader}>
<ActivityIndicator size="large" color="#9E9E9E" />
</View>
)
}
return (
<View style={styles.container}>
<TextInput
style={styles.inputStyle}
placeholder="Name"
value={this.state.displayName}
onChangeText={(val) => this.updateInputVal(val, 'displayName')}
/>
<TextInput
style={styles.inputStyle}
placeholder="Email"
value={this.state.email}
onChangeText={(val) => this.updateInputVal(val, 'email')}
/>
<TextInput
style={styles.inputStyle}
placeholder="Password"
value={this.state.password}
onChangeText={(val) => this.updateInputVal(val, 'password')}
maxLength={15}
secureTextEntry={true}
/>
<Button
color="#3740FE"
title="Signup"
onPress={() => this.registerUser()}
/>
<Text>{this.state.errorMessage}</Text>
<Text
style={styles.loginText}
onPress={() => this.props.navigation.navigate('Login')}>
Already Registered? Click here to login
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
display: "flex",
flexDirection: "column",
justifyContent: "center",
padding: 35,
backgroundColor: '#fff'
},
inputStyle: {
width: '100%',
marginBottom: 15,
paddingBottom: 15,
alignSelf: "center",
borderColor: "#ccc",
borderBottomWidth: 1
},
loginText: {
color: '#3740FE',
marginTop: 25,
textAlign: 'center'
},
preloader: {
left: 0,
right: 0,
top: 0,
bottom: 0,
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#fff'
}
});
login.js文件
import React, { Component } from 'react';
import { StyleSheet, Text, View, TextInput, Button, Alert, ActivityIndicator } from 'react-native';
import firebase from '../database/firebase';
import {AsyncStorage} from 'react-native';
export default class Login extends Component {
constructor() {
super();
this.state = {
email: '',
password: '',
isLoading: false,
errorMessage: ''
}
}
updateInputVal = (val, prop) => {
const state = this.state;
state[prop] = val;
this.setState(state);
}
/**
*
*/
userLogin = () => {
if (this.state.email === '' && this.state.password === '') {
this.setState({
errorMessage: "Enter details to sign in"
})
//Alert.alert('Enter details to signin!')
} else {
this.setState({
isLoading: true,
})
firebase
.auth()
.signInWithEmailAndPassword(this.state.email, this.state.password)
.then((res) => {
console.log(res)
console.log('User logged-in successfully!')
this.setState({
isLoading: false,
email: '',
password: ''
})
AsyncStorage.setItem('isLoggedIn', '1')
this.props.navigation.navigate('Dashboard')
})
.catch(error => this.setState({
errorMessage: 'Wrong email/password',
isLoading: false
}))
}
}
render() {
if (this.state.isLoading) {
return (
<View style={styles.preloader}>
<ActivityIndicator size="large" color="#9E9E9E" />
</View>
)
}
return (
<View style={styles.container}>
<TextInput
style={styles.inputStyle}
placeholder="Email"
value={this.state.email}
onChangeText={(val) => this.updateInputVal(val, 'email')}
/>
<TextInput
style={styles.inputStyle}
placeholder="Password"
value={this.state.password}
onChangeText={(val) => this.updateInputVal(val, 'password')}
maxLength={15}
secureTextEntry={true}
/>
<Button
color="#3740FE"
title="Signin"
onPress={() => this.userLogin()}
/>
{/* style this */}
<Text>{this.state.errorMessage}</Text>
<Text
style={styles.loginText}
onPress={() => this.props.navigation.navigate('Signup')}>
Don't have account? Click here to signup
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
display: "flex",
flexDirection: "column",
justifyContent: "center",
padding: 35,
backgroundColor: '#fff'
},
inputStyle: {
width: '100%',
marginBottom: 15,
paddingBottom: 15,
alignSelf: "center",
borderColor: "#ccc",
borderBottomWidth: 1
},
loginText: {
color: '#3740FE',
marginTop: 25,
textAlign: 'center'
},
preloader: {
left: 0,
right: 0,
top: 0,
bottom: 0,
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#fff'
}
});
dashboard.js文件
import React, { Component } from 'react';
import { StyleSheet, Text, View, TextInput, Button, Alert, ActivityIndicator } from 'react-native';
import firebase from '../database/firebase';
import {AsyncStorage} from 'react-native';
export default class Login extends Component {
constructor() {
super();
this.state = {
email: '',
password: '',
isLoading: false,
errorMessage: ''
}
}
updateInputVal = (val, prop) => {
const state = this.state;
state[prop] = val;
this.setState(state);
}
/**
*
*/
userLogin = () => {
if (this.state.email === '' && this.state.password === '') {
this.setState({
errorMessage: "Enter details to sign in"
})
//Alert.alert('Enter details to signin!')
} else {
this.setState({
isLoading: true,
})
firebase
.auth()
.signInWithEmailAndPassword(this.state.email, this.state.password)
.then((res) => {
console.log(res)
console.log('User logged-in successfully!')
this.setState({
isLoading: false,
email: '',
password: ''
})
AsyncStorage.setItem('isLoggedIn', '1')
this.props.navigation.navigate('Dashboard')
})
.catch(error => this.setState({
errorMessage: 'Wrong email/password',
isLoading: false
}))
}
}
render() {
if (this.state.isLoading) {
return (
<View style={styles.preloader}>
<ActivityIndicator size="large" color="#9E9E9E" />
</View>
)
}
return (
<View style={styles.container}>
<TextInput
style={styles.inputStyle}
placeholder="Email"
value={this.state.email}
onChangeText={(val) => this.updateInputVal(val, 'email')}
/>
<TextInput
style={styles.inputStyle}
placeholder="Password"
value={this.state.password}
onChangeText={(val) => this.updateInputVal(val, 'password')}
maxLength={15}
secureTextEntry={true}
/>
<Button
color="#3740FE"
title="Signin"
onPress={() => this.userLogin()}
/>
{/* style this */}
<Text>{this.state.errorMessage}</Text>
<Text
style={styles.loginText}
onPress={() => this.props.navigation.navigate('Signup')}>
Don't have account? Click here to signup
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
display: "flex",
flexDirection: "column",
justifyContent: "center",
padding: 35,
backgroundColor: '#fff'
},
inputStyle: {
width: '100%',
marginBottom: 15,
paddingBottom: 15,
alignSelf: "center",
borderColor: "#ccc",
borderBottomWidth: 1
},
loginText: {
color: '#3740FE',
marginTop: 25,
textAlign: 'center'
},
preloader: {
left: 0,
right: 0,
top: 0,
bottom: 0,
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#fff'
}
});
答案 0 :(得分:0)
React-Navigation在其官方站点上提供了有关身份验证流程的帮助。只需点击以下链接
https://reactnavigation.org/docs/auth-flow/
注意:您可以通过本文使用钩子和react-navigation 5进行身份验证流程
https://dev.to/embeddednature/create-an-authorization-flow-with-react-navigation-5-x-2pkh