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

React基于localStorage判断跳转时报Maximum update depth exceeded错误如何解决

问题根因
  • 你在工具文件中导出的user是模块加载时一次性计算的静态常量,仅在首次导入工具文件时读取一次localStorage,后续localStorage的更新(登录/退出操作)不会同步更新这个常量的值。
  • 触发无限更新的原因是:未登录状态下这个常量永远为假值,组件每次渲染都会触发重定向,当路由匹配逻辑存在重复触发渲染的情况时,就会进入重定向→渲染→重定向的死循环。你在组件内部每次渲染都实时读取localStorage的话,登录后值会更新,就能跳出循环,因此不会报错。
最优复用方案

方案1:封装工具函数(改动最小)

不要导出静态常量,改为导出每次调用都读取最新localStorage的函数:

// utils/auth.js
export const getCurrentUser = () => {
  const userStr = localStorage.getItem('user');
  return userStr ? JSON.parse(userStr) : null;
};

业务组件使用:

import { getCurrentUser } from '../../utils/auth';

const Dashboard = () => {
  const user = getCurrentUser();
  if (!user) return <Redirect to='/auth' />;
  return <h1>Dashboard</h1>;
};

方案2:封装路由守卫(复用性最高,无需每个组件写判断)

直接封装私有路由组件,所有需要登录权限的路由统一用该组件包裹,完全不用在业务页面写登录判断:

React Router v5 版本

// components/PrivateRoute.js
import { Route, Redirect } from 'react-router-dom';
import { getCurrentUser } from '../utils/auth';

const PrivateRoute = ({ component: Component, ...rest }) => {
  return (
    <Route
      {...rest}
      render={props => 
        getCurrentUser() ? <Component {...props} /> : <Redirect to='/auth' />
      }
    />
  );
};
export default PrivateRoute;

路由配置使用:

import { Switch } from 'react-router-dom';
import PrivateRoute from './components/PrivateRoute';

const App = () => {
  return (
    <Switch>
      <Route path='/auth' component={AuthPage} />
      {/* 所有需要登录的路由统一使用PrivateRoute */}
      <PrivateRoute path='/dashboard' component={Dashboard} />
      <PrivateRoute path='/profile' component={Profile} />
    </Switch>
  );
};

React Router v6 版本

// components/PrivateRoute.js
import { Navigate, Outlet } from 'react-router-dom';
import { getCurrentUser } from '../utils/auth';

const PrivateRoute = () => {
  return getCurrentUser() ? <Outlet /> : <Navigate to='/auth' />;
};
export default PrivateRoute;

路由配置使用:

import { Routes, Route } from 'react-router-dom';
import PrivateRoute from './components/PrivateRoute';

const App = () => {
  return (
    <Routes>
      <Route path='/auth' element={<AuthPage />} />
      <Route element={<PrivateRoute />}>
        {/* 该节点下所有子路由自动继承登录校验 */}
        <Route path='/dashboard' element={<Dashboard />} />
        <Route path='/profile' element={<Profile />} />
      </Route>
    </Routes>
  );
};

方案3:封装自定义Hook(适合需要频繁使用用户信息的场景)

// hooks/useCurrentUser.js
import { useMemo } from 'react';
import { getCurrentUser } from '../utils/auth';

export const useCurrentUser = () => {
  return useMemo(() => getCurrentUser(), []);
};

业务组件使用:

import { useCurrentUser } from '../hooks/useCurrentUser';

const Dashboard = () => {
  const user = useCurrentUser();
  if (!user) return <Redirect to='/auth' />;
  return <h1>欢迎回来,{user.nickname}</h1>;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:15:03