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

React v6结合Firebase实现私有路由时出现currentUser未定义错误如何解决

问题排查与修复方案

错误根源

  1. 直接访问未初始化的用户属性触发报错
    useAuth 初始状态下currentUser为undefined,且Firebase的onAuthStateChanged是异步执行的,组件首次渲染时你直接执行console.log(currentUser.email),相当于读取undefined的属性,自然抛出错误。
  2. 私有路由逻辑写反,存在死循环风险
    你将PrivateRoute包裹在/home路由下,现有逻辑是检测到已登录用户就跳转到/home,会触发无限重定向;已登录状态下应该直接渲染传入的子组件(即首页)才符合需求。
  3. 缺少加载状态,会出现误跳转
    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 17:15:01