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

ReactJS中Protected Route出现Too many re render错误,本地正常服务器报错

问题原因

核心是两个逻辑叠加形成了无限重定向:

  1. localStorage.getItem(key) 当key不存在时返回的是null,不是空字符串,你代码中判断localStorage.getItem('token') === '',对于首次访问的新用户(部署后新环境的localStorage为空),这个条件永远不成立。
  2. 未登录用户访问任意受保护路由时,ProtectedRoute会跳转到/login,但/login的判断条件不成立,又会触发跳转到/,两者循环跳转触发重渲染报错。本地环境因为你之前测试时可能存过空值的token、userId,所以判断刚好成立,不会触发循环。

报错截图

解决步骤

1. 修正Main组件的路由逻辑

删掉Switch内login路由的条件渲染,改成统一的render判断,不要在Switch层级做条件渲染,避免逻辑混乱:

<Switch>
  <ProtectedRoute exact path ={["/home","/"]} component={Dashboard} />
  <ProtectedRoute exact path ="/list" component={List} />
  <ProtectedRoute exact path ="/item" component={Item} />
  <ProtectedRoute exact path ="/item/:id" component={Item} />
  {/* 单独处理login路由逻辑 */}
  <Route exact path="/login" render={(props) => {
    const token = localStorage.getItem('token')
    const userId = localStorage.getItem('userId')
    // 已登录就跳首页,未登录渲染登录页
    return token && userId ? <Redirect to="/" /> : <Login {...props} />
  }} />
</Switch>

2. 优化ProtectedRoute的判断逻辑

把取值转成布尔值,避免空值、null、undefined的判断歧义:

import React from "react";
import { Redirect, Route } from "react-router-dom";

function ProtectedRoute({ component: Component, ...restOfProps }) {
    const token = localStorage.getItem("token");
    const userId = localStorage.getItem('userId');  
    return (
      <Route
        {...restOfProps}
        render={(props) =>
          // 转布尔值判断更稳妥
          !!token && !!userId ? <Component {...props} /> : <Redirect to="/login" />
        }
      />
    );
  }
  
  export default ProtectedRoute;

3. 清理冗余代码

Main组件的handleLogout方法里,你已经把state中的token、userId初始化注释掉了,不需要再调用setState更新这两个不存在的state,删除对应代码避免不必要的重渲染:

handleLogout(){
    // 删掉下面两行没用的setState
    // this.setState({token: ''})
    // this.setState({userId:'' })
    localStorage.setItem('userId','')
    localStorage.setItem('token', '');
    // 退出后跳转到登录页
    window.location.href = '/login'
}

4. 可选优化(提升体验)

登录成功后不要用window.location='/'刷新整页,可以用react-router提供的history方法跳转,修改Login组件的登录成功逻辑:

// login请求成功后
if (response.status === 200 && response.data.token !== '') {
  localStorage.setItem('token', response.data.token);
  localStorage.setItem('userId', response.data.userId);
  // 替换window.location='/'
  this.props.history.push('/')
}

修改完即可解决无限重渲染问题,同时保留受保护路由和登录页的访问控制逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 20:36:01