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

添加Redux Persist后登出触发Maximum update depth exceeded错误排查

问题:添加Redux Persist后登出触发「Maximum update depth exceeded」错误

我在使用Redux Toolkit做状态管理的React应用中,加入Redux Persist后,每次执行登出操作都会触发「Maximum update depth exceeded」错误。之前应用运行正常,我把用户信息存在Cookie里,希望Cookie过期时自动跳转到登录页,但现在完全搞不清错误触发的原因。相关代码如下:

index.js

import ReactDOM from "react-dom";
import {
  BrowserRouter as Router,
  Route,
  Navigate,
  Routes,
} from "react-router-dom";
import { persistor, store } from "./app/store";
import { Provider } from "react-redux";
import ProtectedRoutes from "./utils/ProtectedRoutes";
import NotFound from "./views/Dashboard/Settings/NotFound";
import { PersistGate } from "redux-persist/integration/react";

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <Router>
        <Suspense fallback={<LazyLoad />}>
          <Routes>
            <Route exact element={<ProtectedRoutes />}>
              <Route path={`admin/*`} element={<AdminLayout />} />
              <Route path="/" element={<Navigate to="/admin/dashboard" />} />
            </Route>
            <Route path={`auth/*`} element={<AuthLayout />} />
          </Routes>
        </Suspense>
      </Router>
      </PersistGate>
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

ProtectedRoutes.jsx

import { Navigate, Outlet } from "react-router-dom";
import Cookies from "js-cookie"

export default function ProtectedRoutes() {

  let userid = Cookies.get("user") == null ? false : true;
  return <div>{userid ? <Outlet /> : <Navigate to="/auth/login" />}</div>;
}

登出函数

const logout = async () => {
  const response = await axios.post(
    `${import.meta.env.VITE_BACKEND_LOCAL_URL}/api/v1/auth/logout`
  );

  if (response.data) {
    sessionStorage.removeItem("token");
    sessionStorage.removeItem("user");
    localStorage.removeItem("apiEnv");
  }
  return response.data;
};

问题原因及修复方案

原因分析

这个循环更新错误核心是Redux Persist的持久化操作与路由跳转触发了重复更新循环:

  1. 登出时仅清除了sessionStorage/localStorage,但未处理Redux Persist持久化存储的状态,Persist会自动将旧状态重新同步回store,触发组件反复渲染
  2. ProtectedRoutes每次渲染都直接判断Cookie并返回Navigate,如果Redux Persist的状态同步过程导致组件反复渲染,就会引发路由跳转的无限循环

修复步骤

  1. 登出时清空Redux Persist持久化存储
    修改登出函数,清除常规存储后调用persistor.purge()清空持久化的Redux状态,并手动跳转登录页:

    import { persistor } from "./app/store";
    
    const logout = async () => {
      const response = await axios.post(
        `${import.meta.env.VITE_BACKEND_LOCAL_URL}/api/v1/auth/logout`
      );
    
      if (response.data) {
        sessionStorage.removeItem("token");
        sessionStorage.removeItem("user");
        localStorage.removeItem("apiEnv");
        // 清空Redux Persist的持久化数据
        await persistor.purge();
        // 手动跳转避免循环
        window.location.href = "/auth/login";
      }
      return response.data;
    };
    
  2. 优化ProtectedRoutes的认证判断逻辑
    使用React状态和副作用处理认证判断,避免每次渲染都直接触发跳转:

    import { Navigate, Outlet, useEffect, useState } from "react-router-dom";
    import Cookies from "js-cookie";
    
    export default function ProtectedRoutes() {
      const [isAuthenticated, setIsAuthenticated] = useState(false);
    
      useEffect(() => {
        const checkAuth = () => {
          const hasUser = Cookies.get("user") !== null;
          setIsAuthenticated(hasUser);
        };
        checkAuth();
        // 可选:定时检测Cookie状态,实现过期自动跳转
        const interval = setInterval(checkAuth, 1000);
        return () => clearInterval(interval);
      }, []);
    
      if (!isAuthenticated) {
        return <Navigate to="/auth/login" replace />;
      }
    
      return <Outlet />;
    }
    
  3. 检查Redux Persist配置
    确保store中持久化的slice没有包含会触发无限重渲染的逻辑,比如不要在extraReducers中编写会重复触发action的代码。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 00:52:15