为什么我的反应状态没有正确改变?

时间:2020-05-06 19:22:33

标签: javascript reactjs firebase firebase-authentication

我正在尝试使用firebase进行身份验证。 这是跟踪我的身份验证状态的组件。

    import { useState} from "react";


    function useAuth(fbAuth) {
       const [isAuthenticated, setIsAuthenticated] = useState(false);
       const createEmailUser = (email, password) => fbAuth.createUserWithEmailAndPassword(email, password);
       const signInEmailUser  = (email, password) => fbAuth.signInWithEmailAndPassword(email, password);
       const signOut = fbAuth.signOut();

       fbAuth.onAuthStateChanged(async user=> {
          if (user) {
             await setIsAuthenticated(true);
             console.log(isAuthenticated, "should be true")
             return
          } else {
             await setIsAuthenticated(false);
             console.log(isAuthenticated, "should be false")
             return
          }

        });

       return {isAuthenticated, createEmailUser, signInEmailUser, signOut};

    }

    export default useAuth

单击“登录名”时控制台将登录

2useAuth.js:13假“应该为真”

2useAuth.js:17假“应该是假”

2useAuth.js:17为“应该为假”

4useAuth.js:17假“应该是假”

2 个答案:

答案 0 :(得分:0)

setIsAuthenticated函数不会返回promise,因此在此处使用await并没有任何作用。最重要的是,isAuthenticated的值永远不会被修改(调用setIsAuthenticated不会更改在挂钩开始时已经设置的变量的值)。基本上,在console.log函数中执行onAuthStateChanged是没有道理的,也不会做您期望的事情。如果您想对正在发生的事情有更好的了解,请尝试在函数的开头放置一个console.log,然后打印出您期望它会改变的事实。像这样:

import { useState, useEffect } from "react";

function useAuth(fbAuth) {
   const [isAuthenticated, setIsAuthenticated] = useState(false);
   const createEmailUser = (email, password) => fbAuth.createUserWithEmailAndPassword(email, password);
   const signInEmailUser  = (email, password) => fbAuth.signInWithEmailAndPassword(email, password);
   const signOut = fbAuth.signOut();

   console.log('isAuthenticated', isAuthenticated)
   //I'm assuming you only need to register the fbAuth.onAuthStateChanged
   //callback once. So We use useEffect with an empty array to have it
   //only run the first time this is rendered.
   useEffect(() => {
       fbAuth.onAuthStateChanged(async user=> {
          if (user) {
             setIsAuthenticated(true);
             console.log('isAuthenticated should be true after this')
          } else {
             setIsAuthenticated(false);
             console.log('isAuthenticated should be false after this')
          }
        });
    }, [])

    return {isAuthenticated, createEmailUser, signInEmailUser, signOut};

}

export default useAuth

然后您会期望

//Initial render
isAuthenticated false

//Click log-in
isAuthenticated should be true after this
isAuthenticated true

//Click log-out
isAuthenticated should be false after this
isAuthenticated false

答案 1 :(得分:0)

我在这里没发现错。您正在获取更改之前的值。要访问最新状态,您可以使用useEffect钩子。 另外,您还没有问过类似的问题,您希望什么?