React登录后导航触发Maximum Update Depth Exceeded Error问题求助
错误原因分析
问题出在静态认证状态变量未动态更新:
- 模块级的
isAuthenticated仅在应用初始化时计算一次,登录后localStorage中存入了token,但该变量不会重新读取最新值,始终保持初始的null。 - 登录成功后调用
nav.push("/admin"),ProtectedRoute根据过时的isAuthenticated判断用户未认证,重定向到/auth/signin;此时Redux中已存在登录状态,登录组件再次触发导航到/admin,形成无限跳转循环,导致组件反复更新,触发Maximum update depth exceeded错误。
解决方案
方案1:动态从localStorage获取认证状态
修改路由逻辑,每次渲染时实时读取localStorage的最新值:
- 更新
ProtectedRoute:
const ProtectedRoute = ({ component: Component, ...rest }) => ( <Route {...rest} render={(props) => { const storedToken = localStorage.getItem("token"); const isAuthenticated = storedToken ? JSON.parse(storedToken) : null; return !isAuthenticated ? ( <Redirect to="/auth/signin" /> ) : ( <Component {...props} /> ); }} /> );
- 替换根路由的静态重定向:
// 替换原<Redirect />代码 <Route exact path="/" render={() => { const storedToken = localStorage.getItem("token"); const isAuthenticated = storedToken ? JSON.parse(storedToken) : null; return <Redirect to={!isAuthenticated ? "/auth/signin" : "/admin/dashboard"} />; }} />
方案2:从Redux状态获取认证状态(更可靠)
利用Redux中已存储的token状态,避免localStorage与Redux状态不一致的问题:
- 修改
ProtectedRoute为函数组件,使用useSelector读取Redux状态:
import { useSelector } from 'react-redux'; const ProtectedRoute = ({ component: Component, ...rest }) => { // 假设Redux store中auth切片包含token字段 const token = useSelector(state => state.auth.token); const isAuthenticated = token !== null; return ( <Route {...rest} render={(props) => !isAuthenticated ? ( <Redirect to="/auth/signin" /> ) : ( <Component {...props} /> ) } /> ); };
- 创建动态根重定向组件:
import { useSelector } from 'react-redux'; const RootRedirect = () => { const token = useSelector(state => state.auth.token); const isAuthenticated = token !== null; return <Redirect to={!isAuthenticated ? "/auth/signin" : "/admin/dashboard"} />; }; // 在Switch中替换原<Redirect />代码 <Route exact path="/" component={RootRedirect} />
额外优化建议
- 移除
SigninApi中无效的console.log;语句,改为console.log(response);便于调试。 - 避免直接操作DOM获取表单值(
document.getElementsByName),改用React受控组件通过state管理输入,更符合React数据流模式。
内容的提问来源于stack exchange,提问作者Haseeb Irfan
相关产品推荐
相关产品推荐

