React.js如何阻止已登录用户返回登录页及最大更新深度超限错误解决
最大更新深度报错原因及修复方案
报错触发原因
这个错误由无限重定向循环导致,核心诱因有两点:
- 你的
getCurrentUser方法每次调用都会通过jwtDecode生成全新的对象引用,哪怕本地存储的JWT内容没有任何变化,两次调用的返回值引用地址也不相同。 - 你将登录状态判断逻辑直接写在了
render函数中,只要判断结果为真就返回<Redirect>组件,每次渲染都会触发一次重定向操作,重定向又会触发登录页组件重新渲染,形成死循环,最终触发React的最大更新深度限制报错。
修复方案
你可以选择任意一种适配你项目的方案修复:
方案1:将判断逻辑移出render函数
类组件可以将判断逻辑放到componentDidMount生命周期中,通过state控制重定向,避免每次渲染都触发跳转:
class Login extends React.Component { state = { isLoggedIn: false } componentDidMount() { const user = auth.getCurrentUser() if (user) this.setState({ isLoggedIn: true }) } render() { if (this.state.isLoggedIn) return <Redirect to="/" /> // 原有登录页渲染逻辑 } }
如果是函数组件,对应放到useEffect中实现即可。
方案2:优化getCurrentUser方法,添加缓存逻辑
给getCurrentUser添加返回值缓存,只要JWT没有变化,就返回同一个对象引用,避免不必要的重渲染触发:
import jwtDecode from "jwt-decode"; let cachedUser = null; let lastToken = null; export function getCurrentUser() { try { const jwt = localStorage.getItem("token"); // token未变化时直接返回缓存的用户对象 if (jwt === lastToken) return cachedUser; lastToken = jwt; cachedUser = jwt ? jwtDecode(jwt) : null; return cachedUser; } catch { lastToken = null; cachedUser = null; return null; } } export default { getCurrentUser, };
方案3:简化登录状态判断逻辑
你只是需要判断用户是否登录的场景下,不需要解析JWT内容,直接判断本地是否存在token即可:
render() { if (localStorage.getItem("token")) return <Redirect to="/" />; // 原有登录页渲染逻辑 }
注意:如果你的项目配置了全局路由守卫,需要同时确认首页不会在用户已登录的状态下重定向回登录页,否则会出现两个页面互相跳转的循环问题。
内容的提问来源于stack exchange,提问作者Saadi
相关产品推荐
相关产品推荐

