useEffect 未在 auth.currentUser 更改时更新
useEffect not updating on auth.currentUser change
我想在用户身份验证状态发生变化时更新我的状态(在我的导航页面中):
import {auth} from '../firebase.js' // where auth is initialized with getAuth() from firebase/auth
const Navigation = () => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(()=>{
console.log("Here"); // Gets logged on sign out but not on sign in
setIsAuthenticated(Boolean(auth.currentUser));
}, [auth.currentUser])
return ({isAuthenticated ? <SomeComponent /> : <SomeComponent />})
}
firebase.js
import { getAuth } from "firebase/auth";
const auth = getAuth(firebaseApp);
export {auth}
然后在我的登录组件中我有签名功能,它应该并且正在更新 auth.currentUser:
的值
const signIn = ({ email, password }) => {
signInWithEmailAndPassword(auth, email, password)
.then((resp) => {
console.log(auth.currentUser); // This is working, meaning auth.currentUser value has changed
})
.catch((err) => setFirebaseError(err));
};
只要我注销,它就可以运行并执行,但当用户登录时不执行,我不明白为什么。
我知道 auth.currentUser 变量正在更新,因为我在登录函数中将其打印出来,但出于某种原因 useEffect 无法识别它并且不会触发?
使用 auth.currentUser
将不起作用,因为它或多或少是 firebase 公开的全局变量,不会触发任何类型的反应更新。
您应该做的是在 onAuthStateChanged
上订阅,这将在用户登录或注销时触发,然后使用它来切换您的 isAuthenticated
标志。
对于 firebase v9
import { useState } from "react";
import { getAuth, onAuthStateChanged } from "firebase/auth";
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(() => {
const auth = getAuth();
const listener = onAuthStateChanged(auth, async (user) => {
setIsAuthenticated(!!user);
});
return () => {
listener();
};
}, []);
对于 firebase v8
import { useState } from "react";
import firebase from "firebase";
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(() => {
const listener = firebase.auth().onAuthStateChanged(auth, async (user) => {
setIsAuthenticated(!!user);
});
return () => {
listener();
};
}, []);
或者更好的是,您可以查看 react-firebase-hooks or reactfire,它在 firebase JS SDK 之上提供了一组相当不错的挂钩。
我想在用户身份验证状态发生变化时更新我的状态(在我的导航页面中):
import {auth} from '../firebase.js' // where auth is initialized with getAuth() from firebase/auth
const Navigation = () => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(()=>{
console.log("Here"); // Gets logged on sign out but not on sign in
setIsAuthenticated(Boolean(auth.currentUser));
}, [auth.currentUser])
return ({isAuthenticated ? <SomeComponent /> : <SomeComponent />})
}
firebase.js
import { getAuth } from "firebase/auth";
const auth = getAuth(firebaseApp);
export {auth}
然后在我的登录组件中我有签名功能,它应该并且正在更新 auth.currentUser:
的值const signIn = ({ email, password }) => {
signInWithEmailAndPassword(auth, email, password)
.then((resp) => {
console.log(auth.currentUser); // This is working, meaning auth.currentUser value has changed
})
.catch((err) => setFirebaseError(err));
};
只要我注销,它就可以运行并执行,但当用户登录时不执行,我不明白为什么。
我知道 auth.currentUser 变量正在更新,因为我在登录函数中将其打印出来,但出于某种原因 useEffect 无法识别它并且不会触发?
使用 auth.currentUser
将不起作用,因为它或多或少是 firebase 公开的全局变量,不会触发任何类型的反应更新。
您应该做的是在 onAuthStateChanged
上订阅,这将在用户登录或注销时触发,然后使用它来切换您的 isAuthenticated
标志。
对于 firebase v9
import { useState } from "react";
import { getAuth, onAuthStateChanged } from "firebase/auth";
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(() => {
const auth = getAuth();
const listener = onAuthStateChanged(auth, async (user) => {
setIsAuthenticated(!!user);
});
return () => {
listener();
};
}, []);
对于 firebase v8
import { useState } from "react";
import firebase from "firebase";
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(() => {
const listener = firebase.auth().onAuthStateChanged(auth, async (user) => {
setIsAuthenticated(!!user);
});
return () => {
listener();
};
}, []);
或者更好的是,您可以查看 react-firebase-hooks or reactfire,它在 firebase JS SDK 之上提供了一组相当不错的挂钩。