简体   繁体   English

React Native:useState setter 不会重新渲染

[英]React Native: useState setter doesn't rerender

I'm new to react and javascript.我是新来的反应和 javascript。 I am trying to show an ActivityIndicator while I log in a user, however, the setIsLoading method isn't actually changing the state and calling a rerender.我试图在登录用户时显示 ActivityIndicator,但是,setIsLoading 方法实际上并没有更改 state 并调用重新渲染。 the handleLogin method is called on a button click, and when I click the button, useEffect isn't printed to the console which means it isn't being called. handleLogin 方法在单击按钮时被调用,当我单击按钮时,useEffect 不会打印到控制台,这意味着它没有被调用。 Also, console.log(isLoading) still shows the value as false which it is initialized to.此外,console.log(isLoading) 仍将值显示为 false,它被初始化为。 Strangely I was able to get it to work when I commented out the entire firebase section, and I was wondering if anyone could help me understand why that is?奇怪的是,当我注释掉整个 firebase 部分时,我能够让它工作,我想知道是否有人可以帮助我理解为什么会这样? Thank you.谢谢你。

import React, { useState, useEffect } from 'react'
import firebase from '../firebase'
import { ActivityIndicator, StyleSheet, Text, TextInput, View, Button} from 'react-native'
export default function LoginScreen({navigation}) {
    const [email, setEmail] = useState('')
    const [password, setPassword] = useState('')
    const [errorMessage, setErrorMessage] = useState(null)
    const [isLoading, setIsLoading] = useState(false)
    const [showLoader, setShowLoader] = useState(false)

    useEffect(() => {
        setShowLoader(isLoading)
        console.log('useEffect')
    },[isLoading])

    const handleLogin = () => { 
        setIsLoading(true)
        console.log(isLoading)

        firebase.auth().signInWithEmailAndPassword(email, password)
        .then(() => { navigation.navigate('Home')})
        .then(setIsLoading(false))
        .catch((error) => {setErrorMessage(error.message)})

        console.log('handleLogin')
    }
    return (
      <View style={styles.container}>
        <Text>Login</Text>
        {errorMessage &&
          <Text style={{ color: 'red' }}>
            {errorMessage}
          </Text>}
        <TextInput
          style={styles.textInput}
          autoCapitalize="none"
          placeholder="Email"
          onChangeText={email => setEmail(email)}
          value={email}
        />
        <TextInput
          secureTextEntry
          style={styles.textInput}
          autoCapitalize="none"
          placeholder="Password"
          onChangeText={password => setPassword(password)}
          value={password}
        />
        <Button title="Login" onPress={handleLogin} />
        <Button
          title="Don't have an account? Sign Up"
          onPress={() => navigation.navigate('SignUp')}
        />
        {
            showLoader && <ActivityIndicator/>
        }   
      </View>
    )
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  textInput: {
    height: 40,
    width: '90%',
    borderColor: 'gray',
    borderWidth: 1,
    marginTop: 8
  }
})

Edit: Thank you, I figured out that useEffect isn't called until the method handleLogin is completed, so isLoading is set to true, but then set to false again after the signin procedure, and so when it comes time for useEffect to be called, it sees that the isLoading state hasn't changed and so useEffect isn't called.编辑:谢谢,我发现直到方法 handleLogin 完成后才会调用 useEffect,所以 isLoading 设置为 true,但在登录过程之后再次设置为 false,所以到时候调用 useEffect ,它看到 isLoading state 没有改变,所以 useEffect 没有被调用。 If anyone has any ideas as to how to get around this flow (so useEffect is called before the signin procedure or something) I would greatly appreciate it.如果有人对如何绕过这个流程有任何想法(所以在登录过程之前调用 useEffect 或其他东西),我将不胜感激。 Thanks!谢谢!

It seems you are navigating out of the screen before setIsLoading can be executed, although I don't know if it can be the problem without the rest of the code.在执行 setIsLoading 之前,您似乎正在导航出屏幕,尽管我不知道如果没有代码的 rest 是否会出现问题。

console.log(isLoading) is false because useState is asyncronous, setIsLoading is a promise not yet solved when the next line of code is reached. console.log(isLoading) 是 false 因为 useState 是异步的,setIsLoading 是一个 promise 在到达下一行代码时尚未解决。

This line of code isLoading? setShowLoader(true): setShowLoader(false)这行代码isLoading? setShowLoader(true): setShowLoader(false) isLoading? setShowLoader(true): setShowLoader(false) would be cleaner as setShowLoader(isLoading) isLoading? setShowLoader(true): setShowLoader(false)会像setShowLoader(isLoading)一样干净

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

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