嗨!我是 React Native 的新手。最近我开发了一个可以正常工作的 expo 应用程序,但是我的登录屏幕面临一个问题是,当我第一次尝试输入用户名和密码时按下登录按钮,当我控制台记录数据设置的状态时AsyncStorage 帮助我在登录后进行处理,但这些状态未定义。第二次按下登录成功。
国家这种行为的原因是什么?
import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, TextInput, Button, ScrollView } from 'react-native';
import { Card } from "react-native-shadow-cards";
import Constants from 'expo-constants';
import axios from 'react-native-axios';
import AsyncStorage from '@react-native-async-storage/async-storage';
const Login = ({ navigation }) => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [isLoggedIn,setIsLoggedIn] = useState();
const [role, setRole] = useState();
const [auth, setAuth] = useState('false');
const authCred = {
"username": username,
"password": password,
}
console.log(authCred);
const login = async () => {
try{
const resp = await axios.post("https://hebruapp.herokuapp.com/api/login/", authCred);
const designation = String(resp.data.role)
//await AsyncStorage.setItem('isLoggedIn', '1')
await AsyncStorage.multiSet([['isLoggedIn', '1'], ['role', designation]])
const dataKeys =['isLoggedIn', 'role'];
const getKeysData = async (keys) => {
const stores = await AsyncStorage.multiGet(keys);
const aData = stores.map(([key, value]) => ({[key]: value}))
setIsLoggedIn(aData[0]['isLoggedIn'])
setRole(aData[1]['role'])
}
getKeysData(dataKeys)
console.log('keystart')
console.log(isLoggedIn)
console.log(role)
console.log('keyend')
if (isLoggedIn == '1'){
if(role == 'true'){
console.log('adminSide')
navigation.navigate('App');
navigation.navigate('Data',{
role:true
});
}else if(role == 'false'){
console.log('userSide')
navigation.navigate('UserApp');
navigation.navigate('Data',{
role:false
});
}
}else{
navigation.navigate('Auth');
}
}catch(error){
if(error.response){
console.log('Username is incorrect')
alert("Username/Password is incorrect");
setUsername('');
setPassword('')
}
}
}
return (
<ScrollView>
<Card style={styles.containerLogin} >
<Text style={styles.titlePage}>Login</Text>
<Text style={styles.bold}>Username:</Text>
<TextInput
style={styles.textinput}
placeholder="Type a email"
onChangeText={username => setUsername(username)}
defaultValue={username}
/>
<Text style={[styles.bold, styles.password]}>Password:</Text>
<TextInput
style={styles.textinput}
placeholder="Type a password"
onChangeText={password => setPassword(password)}
defaultValue={password}
secureTextEntry={true}
/>
<View style={styles.loginButton} >
<Button color="black" title="Login" onPress={()=>{login()}} />
</View>
</Card>
</ScrollView>
)
}
const styles = StyleSheet.create({
containerLogin: {
flex: 1,
backgroundColor: "radial-gradient(ellipse at left bottom, rgb(163, 237, 255) 0%, rgba(57, 232, 255, 0.9) 59%, rgba(48, 223, 214, 0.9) 100% )",
marginVertical: 125,
marginLeft: 20,
paddingLeft: 30,
paddingRight: 30,
alignItems: 'center',
justifyContent: 'center',
borderRadius: 60,
},
textinput: {
height: 40,
width: 250,
borderColor: 'gray',
borderWidth: 1,
padding: 10,
backgroundColor: 'white',
},
bold: {
fontWeight: 'bold',
justifyContent: 'center',
},
titlePage: {
fontWeight: 'bold',
fontSize: 30,
marginBottom: 20
},
password: {
margin: 20,
marginBottom: 0,
},
loginButton: {
marginTop: 25,
},
link: {
marginTop: 10,
},
linkSignup: {
marginTop: 8,
textDecorationLine: 'underline',
color: 'white',
}
})
export default Login
我遇到了这些状态的问题,
const [isLoggedIn,setIsLoggedIn] = useState();
const [role, setRole] = useState();
答案 0 :(得分:1)
const getKeysData = async (keys) => {
const stores = await AsyncStorage.multiGet(keys);
const aData = stores.map(([key, value]) => ({[key]: value}))
setIsLoggedIn(aData[0]['isLoggedIn'])
setRole(aData[1]['role'])
}
getKeysData(dataKeys)
不等待 getKeysData 会导致问题。该函数将在 AsyncStorage.get 返回之前继续执行。即使您确实在等待它,反应状态也会在下一次渲染时更新,而不是立即更新。
但是,看起来 role 和 isLoggedIn 甚至没有在您的组件中使用,仅在登录功能中使用。因此,将它们改为局部变量并将它们从反应状态中移除。
答案 1 :(得分:0)
通过在钩子的参数中传递一些东西来设置初始值
例如
const [isLoggedIn,setIsLoggedIn] = useState(false);
const [role, setRole] = useState("");