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

Firebase Auth onAuthStateChanged未登录即跳转问题求助

问题分析与修复方案

你遇到的未登录时自动跳转首页的问题,主要源于身份验证订阅逻辑错误、代码拼写/语法错误,以及路由跳转未做页面判断这几个点,以下是具体修复步骤和修正后的代码:

核心问题点

  1. useEffect依赖错误:依赖userName会导致重复订阅onAuthStateChanged,且未在组件卸载时取消订阅,引发逻辑混乱
  2. 未处理用户未登录的场景:当user为null时未做路由控制,加上组件可能在多页面渲染,导致错误跳转
  3. 多处语法/拼写错误:比如setUser = (result.user)的赋值错误、SignOut拼写错误、navigate.push使用错误、displayname属性名拼写错误

修复后的完整代码

import styled from "styled-components";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { auth, provider } from "../firebase";
import {
  selectUserName,
  selectUserPhoto,
  setUserLoginDetails,
  setSignOutState
} from "../features/user/userSlice";
import { getAuth, signInWithPopup, GoogleAuthProvider, onAuthStateChanged, signOut } from "firebase/auth";
import { useEffect } from "react";

const Header = (props) => {
  const dispatch = useDispatch();
  const navigate = useNavigate();
  const userName = useSelector(selectUserName);
  const userPhoto = useSelector(selectUserPhoto);

  useEffect(() => {
    // 订阅身份状态变化,组件卸载时取消订阅避免内存泄漏
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      if (user) {
        setUser(user);
        // 仅当当前不在首页时才跳转,避免重复跳转
        if (window.location.pathname !== "/home") {
          navigate("/home");
        }
      } else {
        // 用户未登录时,仅当当前不在登录页时跳转
        if (window.location.pathname !== "/Login") {
          navigate("/Login");
        }
        dispatch(setSignOutState());
      }
    });

    return unsubscribe;
  }, [dispatch, navigate]); // 依赖改为稳定的dispatch和navigate

  const handleAuth = () => {
    if (!userName) {
      signInWithPopup(auth, provider)
        .then((result) => {
          setUser(result.user); // 修复赋值错误
        })
        .catch((error) => {
          alert(error.message);
        });
    } else {
      signOut(auth) // 修复SignOut拼写错误
        .then(() => {
          dispatch(setSignOutState());
          navigate("/Login"); // 修复navigate使用方式(v6中无push方法)
        })
        .catch((err) => alert(err.message));
    }
  };

  const setUser = (user) => {
    dispatch(
      setUserLoginDetails({
        name: user.displayName, // 修复displayname拼写错误(应为displayName)
        email: user.email,
        photo: user.photoURL,
      })
    );
  };

  // 补充Header的JSX渲染逻辑(原代码中缺失)
  return (
    <StyledHeader>
      {/* 根据userName显示登录/退出按钮及用户信息 */}
      {!userName ? (
        <button onClick={handleAuth}>登录</button>
      ) : (
        <div>
          <img src={userPhoto} alt={userName} />
          <button onClick={handleAuth}>退出</button>
        </div>
      )}
    </StyledHeader>
  );
};

// 补充styled-components定义(原代码中缺失)
const StyledHeader = styled.header`
  // 可根据需求添加样式
`;

export default Header;

额外建议

  • 将身份验证的路由守卫逻辑抽离到单独组件(比如PrivateRoute),避免在Header中处理路由跳转,让组件职责更清晰
  • 确保Redux的userSlice初始状态中userName为null或空字符串,避免初始状态判断错误

内容的提问来源于stack exchange,提问作者Kundan Agrawal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 10:30:50