You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React自定义Hook中Firebase登录状态布尔值异常切换问题求助

Firebase认证状态检测Hook路由异常问题排查与修复

问题现象

自定义useAuthStatus Hook用于检测Firebase认证状态,在PrivateRoute组件中使用时,页面会先进入主页随即跳转到登录页;打印loggedIn值发现其初始为true,随后突然变为false,不符合预期的路由拦截逻辑。

原因分析

  1. PrivateRoute加载状态处理失效:if(checkingStatus)代码块未返回JSX,导致认证状态检查过程中,组件依然会执行后续的路由判断逻辑,提前根据当前loggedIn值进行跳转。
  2. Hook未同步登出状态:原Hook仅在用户存在时设置loggedIn = true,但当用户认证失效(如会话过期、初始校验失败)时,未主动将loggedIn设为false,导致状态残留。
  3. Firebase异步回调的特性:onAuthStateChanged是异步执行的,若Firebase缓存了历史登录状态,可能先触发一次用户存在的回调,后续校验发现会话无效后再次触发用户不存在的回调,造成loggedIn状态波动。

修复方案

1. 修复PrivateRoute组件

确保加载状态时返回加载UI,并且正确返回受保护内容或跳转组件:

import { Navigate, Outlet } from 'react-router-dom'
import { useAuthStatus } from '../hooks/useAuthStatus'

const PrivateRoute = () => {
  const { loggedIn, checkingStatus } = useAuthStatus()  

  // 认证状态检查中,显示加载提示
  if (checkingStatus) {
    return <h3>Loading...</h3>
  }

  // 已登录则渲染受保护路由内容,未登录跳转至登录页
  return loggedIn ? <Outlet /> : <Navigate to="/login" />
}

export default PrivateRoute

2. 修复useAuthStatus Hook

完善状态同步逻辑,添加监听清理函数,避免内存泄漏:

import { useState, useEffect, useRef } from "react";
import { onAuthStateChanged, getAuth } from "firebase/auth";

export const useAuthStatus = () => {
  const [loggedIn, setLoggedIn] = useState(false);
  const [checkingStatus, setCheckingStatus] = useState(true);
  const isMounted = useRef(true);

  useEffect(() => {
    const auth = getAuth();
    // 订阅Firebase认证状态变化,获取取消订阅函数
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      if (isMounted.current) {
        // 统一处理用户存在/不存在的情况,同步状态
        setLoggedIn(!!user);
        setCheckingStatus(false);
      }
    });

    // 组件卸载时取消订阅,标记组件已卸载
    return () => {
      unsubscribe();
      isMounted.current = false;
    };
  }, []); // 空依赖数组确保仅在组件挂载时初始化监听

  return { loggedIn, checkingStatus };
};

关键修复点说明

  • 状态同步优化:使用setLoggedIn(!!user)直接将用户对象转换为布尔值,确保用户存在/不存在时状态都能正确更新。
  • 内存泄漏防护:添加unsubscribe()清理函数,取消Firebase的认证状态监听,避免组件卸载后回调仍执行。
  • 加载状态正确处理:PrivateRoute中在checkingStatus为true时返回加载UI,阻止提前执行路由判断逻辑。

内容的提问来源于stack exchange,提问作者Srijan Majumder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 13:41:11