React中useAuthListener Hook的返回时机与依赖数组疑问
关于Firebase v8自定义Auth Hook的两个疑问
我正在跟随YouTube教程,使用Firebase v8构建全栈Instagram克隆项目,对以下检测用户登录状态的自定义Hook存在疑问:
import { useState, useEffect, useContext } from "react"; import FirebaseContext from "../context/firebase"; export default function useAuthListener() { const [user, setUser] = useState( JSON.parse(localStorage.getItem("authUser")) ); const { firebase } = useContext(FirebaseContext); useEffect(() => { const listener = firebase.auth().onAuthStateChanged((authUser) => { if (authUser) { // we have a user...therefore we can store the user in localstorage localStorage.setItem("authUser", JSON.stringify(authUser)); setUser(authUser); } else { // we don't have an authUser, therefore clear the localstorage localStorage.removeItem("authUser"); setUser(null); } }); return () => listener(); }, [firebase]); return { user }; }
我们通过该Hook判断用户登录状态以实现组件的条件渲染,我的疑问如下:
疑问1:localStorage已有用户信息时,Hook会立即返回缓存还是等待Firebase校验?
- 第一次渲染时,Hook会立即返回localStorage中存储的用户信息——因为useState的初始值直接取自
localStorage.getItem("authUser"),这个过程是同步的,不需要等待useEffect执行。 - 组件挂载完成后,useEffect会触发Firebase的
onAuthStateChanged监听,这个监听会和Firebase服务器校验当前登录状态:- 如果localStorage里的用户信息有效(比如token未过期、用户未登出),Firebase会返回最新的authUser对象,Hook会更新user状态并同步到localStorage;
- 如果用户已登出或信息失效,Firebase会返回null,Hook会清空localStorage并将user状态设为null。
简单来说:初始用缓存快速返回状态,后续会根据服务器校验结果更新真实状态。
疑问2:firebase是常量,是否需要加入useEffect的依赖数组?
需要加入。原因如下:
- 虽然firebase实例通常是全局常量,但
useContext(FirebaseContext)返回的firebase对象,在Provider重新渲染时可能会被视为新的引用(即使实例本身没变); - 不加入依赖数组会触发React Hooks的lint报错,不符合规范;
- 极端情况下,若firebase引用变化但useEffect未重新执行,会导致登录状态监听失效,无法同步最新的用户状态。
内容的提问来源于stack exchange,提问作者Aaryan
相关产品推荐
相关产品推荐

