繁体   English   中英

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

[英]Why Initial states are undefined in react native?

海。 我是反应原生的新手。 最近我开发了一个 expo 应用程序,该应用程序工作正常,但我的登录屏幕面临的一个问题是,当我输入用户名和密码时,在第一次尝试时按下登录按钮,当我控制台记录设置数据的状态时AsyncStorage 帮助我在登录后进行处理,但这些状态是未定义的。 第二次按登录成功。

state 出现这种行为的原因是什么?

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 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 会导致问题。 function 将在 AsyncStorage.get 返回之前继续执行。 即使您确实等待它,反应 state 也会在下一次渲染时更新,而不是立即更新。

但是,看起来角色和 isLoggedIn 甚至没有在您的组件中使用,仅在登录 function 中使用。 因此,将它们改为局部变量并将它们从反应 state 中删除。

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

例如,

const [isLoggedIn,setIsLoggedIn] = useState(false);
const [role, setRole] = useState("");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM