为什么初始状态在本机反应中未定义?

Why Initial states are undefined in 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();

通过在钩子的参数中传递一些东西来设置初始值

例如,

const [isLoggedIn,setIsLoggedIn] = useState(false);
const [role, setRole] = useState("");
    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 甚至没有在您的组件中使用,仅在登录功能中使用。所以让它们成为局部变量并将它们从反应状态中移除。