添加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的持久化操作与路由跳转触发了重复更新循环:
- 登出时仅清除了sessionStorage/localStorage,但未处理Redux Persist持久化存储的状态,Persist会自动将旧状态重新同步回store,触发组件反复渲染
ProtectedRoutes每次渲染都直接判断Cookie并返回Navigate,如果Redux Persist的状态同步过程导致组件反复渲染,就会引发路由跳转的无限循环
修复步骤
登出时清空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; };优化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 />; }检查Redux Persist配置
确保store中持久化的slice没有包含会触发无限重渲染的逻辑,比如不要在extraReducers中编写会重复触发action的代码。
内容的提问来源于stack exchange,提问作者user22125377
相关产品推荐
相关产品推荐

