React v6结合Firebase实现私有路由时出现currentUser未定义错误如何解决
问题排查与修复方案
错误根源
- 直接访问未初始化的用户属性触发报错
useAuth初始状态下currentUser为undefined,且Firebase的onAuthStateChanged是异步执行的,组件首次渲染时你直接执行console.log(currentUser.email),相当于读取undefined的属性,自然抛出错误。 - 私有路由逻辑写反,存在死循环风险
你将PrivateRoute包裹在/home路由下,现有逻辑是检测到已登录用户就跳转到/home,会触发无限重定向;已登录状态下应该直接渲染传入的子组件(即首页)才符合需求。 - 缺少加载状态,会出现误跳转
Firebase拉取当前用户身份是异步操作,在校验完成前currentUser一直是初始值,此时直接判断跳转,会导致已登录用户首次访问页面时被误跳转到登录页。
修复后的完整代码
1. 调整firebase.js的useAuth逻辑,新增加载状态
// Initialize Firebase export const app = initializeApp(firebaseConfig); export const auth = getAuth(app); export function useAuth() { // 给初始状态明确设为null,避免undefined判断异常 const [currentUser, setCurrentUser] = useState(null); // 新增身份校验加载状态 const [loading, setLoading] = useState(true); useEffect(() => { const unsub = onAuthStateChanged(auth, user => { setCurrentUser(user); // 身份校验完成,关闭加载态 setLoading(false); }); return unsub; }, []) return { currentUser, loading }; }
2. 重写PrivateRoute.js逻辑
export default function PrivateRoute({ children }) { const { currentUser, loading } = useAuth(); // 身份校验过程中显示加载提示,避免错误跳转 if (loading) return <div>身份校验中...</div>; // 不要直接读取currentUser的属性,需要先判断存在再操作 // if(currentUser) console.log(currentUser.email) // 已登录则渲染子组件,未登录跳转登录页 return currentUser ? children : <Navigate to="/signin" />; }
3. 可选优化:实现登录用户访问登录/注册页自动跳首页
你之前给路由加的restricted属性没有生效逻辑,可以新增PublicRoute组件处理公开路由的权限:
// PublicRoute.js export default function PublicRoute({ children }) { const { currentUser, loading } = useAuth(); if (loading) return <div>加载中...</div>; // 已登录用户访问登录注册页直接跳首页 return currentUser ? <Navigate to="/home" /> : children; }
调整App.js的路由配置:
function App() { return ( <Routes> {/* 登录注册页用PublicRoute包裹 */} <Route path='/signin' element={ <PublicRoute> <SignInSide/> </PublicRoute> }/> <Route path='/signup' element={ <PublicRoute> <SignUpside/> </PublicRoute> }/> {/* 首页用私有路由包裹 */} <Route path="/home" element={ <PrivateRoute> <Home/> </PrivateRoute> } /> </Routes> ); }
内容的提问来源于stack exchange,提问作者Diana Sk
相关产品推荐
相关产品推荐

