Почему мое состояние реакции не меняется должным образом? - PullRequest
2 голосов
/ 06 мая 2020

Я пытаюсь аутентифицироваться с помощью 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 false "должно быть истина"

2useAuth. js: 17 false "должно быть false"

2useAuth. js: 17 true "должно быть false"

4useAuth. js: 17 false " должно быть ложным "

Ответы [ 2 ]

0 голосов
/ 06 мая 2020

Я не вижу здесь ничего плохого. Вы получаете значение до того, как оно будет изменено. Для доступа к самому новому состоянию вы можете использовать хук useEffect . Также вы не спрашивали ничего вроде того, в чем ваша проблема и чего вы ожидаете?

0 голосов
/ 06 мая 2020

Функция setIsAuthenticated не возвращает обещание, поэтому использование 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
...