React useEffect内调用Firestore获取单文档无控制台输出问题
问题现象
在useEffect钩子内编写Firestore单文档拉取逻辑时,控制台无日志输出;相同逻辑移到useEffect外部时,docRef、文档数据、文档ID都能正常打印。
问题代码如下:
export function MaterialCard() { const [material, setMaterial] = useState({}); const location = useLocation() const { id } = useParams(); useEffect(() => { const getDocument = async () => { try { const docRef = doc(db, "materials", id); console.log(docRef); const docSnap = await getDoc(docRef).then((doc) => { console.log(doc.data(), doc.id); }); if (docSnap.exists()) { setMaterial(docSnap.data()); } else { console.log("No such document!"); } } catch (e) { console.log(e) }; getDocument(); } }, [])
故障原因
- 函数调用位置错误:
getDocument()的调用语句写在了getDocument函数体内部,useEffect执行时只会定义函数,永远不会触发外层调用,写在函数内部的自调用还会造成无终止递归,直接触发栈溢出。 - 异步写法混用错误:同时使用
async/await和.then()链式调用,且.then()回调没有返回值,await得到的docSnap实际为undefined,后续执行docSnap.exists()会直接抛出类型错误。 - 依赖配置错误:
useEffect依赖数组为空,既没有把用到的路由参数id加入依赖,也没有做id的空值判断,首次渲染如果id还未初始化完成,会直接拉取无效路径文档,后续id更新也不会重新触发请求。
修复方案
调整函数调用位置、统一异步写法、补全依赖和空值判断,修正后代码:
export function MaterialCard() { const [material, setMaterial] = useState({}); const location = useLocation() const { id } = useParams(); useEffect(() => { if (!id) return; const getDocument = async () => { try { const docRef = doc(db, "materials", id); console.log(docRef); const docSnap = await getDoc(docRef); console.log(docSnap.data(), docSnap.id); if (docSnap.exists()) { setMaterial(docSnap.data()); } else { console.log("No such document!"); } } catch (e) { console.log(e) } }; getDocument(); }, [id]) }
内容的提问来源于stack exchange,提问作者Trishka1111
相关产品推荐
相关产品推荐

