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

React中loggedIn状态自动回退为false的问题排查与修复

问题:Google登录后Redux状态loggedIn自动变回false,页面跳转后回到登录页

我添加了Google按钮用于谷歌账号登录,Redux中有一个名为loggedIn的状态属性,初始值为false。点击Google按钮登录时,会dispatch login reducer,状态更新为true并导航到home页面,但状态随即又更新为false,页面回到登录页。


问题原因

  1. signInWithRedirect的异步重定向特性:signInWithRedirect是异步操作,会触发页面重定向刷新。当前代码中在调用它后立刻dispatch login并导航,页面刷新后Redux状态会重置为初始值(Redux默认不持久化状态),导致loggedIn变回false。
  2. 未同步Firebase与Redux状态:页面刷新后,没有检查Firebase的实际用户登录状态,Redux状态无法与Firebase用户状态同步。
  3. Navbar登出逻辑错误:登出按钮直接调用auth.signOut()但未关联Redux的logout dispatch,不过这不是当前问题的直接诱因。

修复方案

1. 处理Google登录重定向结果

修改Authentication.jsx,在组件挂载时处理重定向后的登录结果,确保登录成功后再更新状态:

import React, { useState, useEffect } from 'react';
import SignIn from '../components/SignIn';
import SignUp from '../components/SignUp';
import { auth } from '../firebase/firebase';
import { signInWithRedirect, GoogleAuthProvider, getRedirectResult } from 'firebase/auth';
import GoogleButton from 'react-google-button';
import { useNavigate } from 'react-router-dom';
import { login } from '../redux/slice';
import { useDispatch } from 'react-redux';

const Authentication = () => {
  const [page, setPage] = useState(true);
  const [data, setData] = useState({ email: '', password: '' });
  const [signUpData, setSignUpdData] = useState({
    firstName: '',
    lastName: '',
    email: '',
    password: '',
    confirmPassword: '',
    phoneNumber: '',
    dateOfBirth: '',
  });

  const pageHandler = () => {
    setPage(!page);
  };

  const dataHandler = event => {
    event.preventDefault();
    setData({ ...data, [event.target.name]: event.target.value });
  };

  const signUpDataHandler = event => {
    event.preventDefault();
    setSignUpdData({ ...signUpData, [event.target.name]: event.target.value });
  };

  const navigate = useNavigate();
  const dispatch = useDispatch();

  // 处理Google登录重定向结果
  useEffect(() => {
    const handleRedirectResult = async () => {
      try {
        const result = await getRedirectResult(auth);
        if (result?.user) {
          dispatch(login());
          navigate('/', { replace: true });
        }
      } catch (error) {
        console.error('登录失败:', error);
      }
    };
    handleRedirectResult();
  }, [dispatch, navigate]);

  // Google Button sign in
  const signInWithGoogle = () => {
    const provider = new GoogleAuthProvider();
    signInWithRedirect(auth, provider);
  };

  return (
    <div className="container mt-5">
      <div className="card mx-auto w-75 bg-success p-4">
        <div className="card-body ">
          {page ? (
            <SignIn data={data} dataHandler={dataHandler} />
          ) : (
            <SignUp
              signUpData={signUpData}
              signUpDataHandler={signUpDataHandler}
            />
          )}
        </div>
      </div>
      <div className="d-flex w-75 mx-auto my-3 align-items-center">
        <hr className="w-100 m-0 p-0" />
        <p className="m-0 mx-3">or</p>
        <hr className="w-100 m-0 p-0" />
      </div>
      <div className="d-flex justify-content-center">
        <div>
          <GoogleButton onClick={signInWithGoogle} />
        </div>
      </div>
      <button
        className="btn btn-outline-success mx-auto d-block my-3"
        onClick={pageHandler}>
        {page ? 'Sign Up' : 'Sign In'}
      </button>
    </div>
  );
};

export default Authentication;

2. 同步Firebase与Redux状态

修改App.jsx,监听Firebase用户状态,确保页面刷新后Redux状态与实际登录状态同步:

import React, { useEffect } from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/js/bootstrap.min.js';
import 'bootstrap-icons/font/bootstrap-icons.css';
import Home from './pages/Home';
import Authentication from './pages/Authentication';
import { Routes, Route, Navigate } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import { auth } from './firebase/firebase';
import { useAuthState } from 'react-firebase-hooks/auth';
import { login, logout } from './redux/slice';

const App = () => {
  const { loggedIn } = useSelector(state => state.item);
  const dispatch = useDispatch();
  const [user] = useAuthState(auth);

  // 根据Firebase用户状态同步Redux
  useEffect(() => {
    if (user) {
      dispatch(login());
    } else {
      dispatch(logout());
    }
  }, [user, dispatch]);

  console.log("App", loggedIn);
  let routes;

  if (loggedIn) {
    routes = (
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/home" element={<Home />} />
        <Route path="/logout" element={<Authentication />} />
        <Route
          path="*"
          element={<Navigate to="/" replace />}
        />
      </Routes>
    );
  } else {
    routes = (
      <Routes>
        <Route path="/auth" element={<Authentication />} />
        <Route
          path="*"
          element={<Navigate to="/auth" replace />}
        />
      </Routes>
    );
  }

  return <> {routes} </>;
};

export default App;

3. 修复Navbar登出逻辑

修改Navbar.jsx,确保登出时同步更新Firebase和Redux状态:

import React from 'react';
import './navbar.scss';
import { Link } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { logout } from '../redux/slice';
import { auth } from '../firebase/firebase';

const Navbar = ({ user }) => {
  console.log('nav', user);

  const dispatch = useDispatch();

  const signOut = () => {
    auth.signOut();
    dispatch(logout());
  };

  return (
    <div className="bg-success navigation">
      <div className="chats d-flex flex-column align-items-center">
        <Link to="/">
          <i className="bi bi-house text-light" style={{ fontSize: '30px' }} />
        </Link>
        <Link to="/logout">
          <i
            className="bi bi-sign-turn-left text-light"
            onClick={signOut}
            style={{ fontSize: '30px' }}
          />
        </Link>
      </div>
      <div className="profile">
        <Link to="/" className="profile-link">
          <img
            className="profile-picture"
            src="https://res.cloudinary.com/djz3p8sux/image/upload/v1660556173/image/IMG_20220703_174147_w8fbhq.jpg"
            alt="profile-picture"
          />
        </Link>
      </div>
    </div>
  );
};

export default Navbar;

内容的提问来源于stack exchange,提问作者Mahbubul Hasan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:36:15