React自定义钩子从firebase获取文档isLoading总是false



我创建了这个自定义钩子来获取(在本例中是监听)firestore中的文档:

import { doc, onSnapshot } from 'firebase/firestore';
import { useEffect, useState } from 'react';
import { db, auth } from '../../firebase';
function useCurrentUser() {
const userId = auth.currentUser.uid;
const [user, setUser] = useState({});
const [isUserLoading, setIsUserLoading] = useState(false);
const [isUserError, setIsUserError] = useState(null);
useEffect(() => {
const getUser = async () => {
try {
setIsUserLoading(true);
const userRef = doc(db, 'users', userId);
const unsub = await onSnapshot(userRef, doc => {
setUser(doc.data());
});
} catch (error) {
setIsUserError(error);
} finally {
setIsUserLoading(false);
}
};
getUser();
}, []);
return { user, isUserLoading, isUserError };
}
export default useCurrentUser;

问题是:isUserLoading总是返回false,即使在try语句中,我将其设置为true

知道为什么会这样吗?

onSnapshot返回一个函数,而不是一个承诺,所以你不能await

所以你要做的是:

useEffect(() => {
setIsUserLoading(true);
const userRef = doc(db, 'users', userId);
const unsub = onSnapshot(userRef, snapshot => {
if(!snapshot.exists()) return
setIsUserLoading(false);
setUser(snapshot.data());
});
return unsub
}, []);

在您当前的代码中,finally将立即运行,因为没有什么等待

From w3schools.com:

try语句定义了要运行(尝试)的代码块。

catch语句定义一个代码块来处理任何错误。

finally语句定义了一个不管结果如何都要运行的代码块。

所以你在try中设置它为true然后在之后设置回false

最新更新