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

React useEffect:如何解决Maximum update depth exceeded无限循环错误?

问题修复:React组件无限循环(Maximum update depth exceeded)

问题原因

你的Landing组件触发无限循环,核心问题有两点:

  • 当userDetails不存在、userType不匹配任何分支时,没有对应的跳转逻辑,组件停留在当前页面,useEffect每次渲染都会执行redirectToDashboard,重复触发navigate
  • 即使匹配到userType,如果目标路由配置错误(比如目标路由又重定向回Landing),或者重复调用navigate到当前路由,会触发组件重新渲染,进而再次执行useEffect形成循环

另外,redirectToDashboard函数每次组件渲染都会重新创建,你用eslint-disable忽略了依赖警告,这也可能隐藏潜在的依赖问题。

修复步骤

1. 完善分支逻辑,覆盖所有边界情况

在redirectToDashboard中添加默认分支,避免无意义的循环:

const redirectToDashboard = () => {
  if (isLoggedIn) {
    switch(userDetails?.userType) {
      case "CANDIDATE":
        navigate(ROUTES.CANDIDATE.DASHBOARD.PATH);
        break;
      case "COMPANY":
        navigate(ROUTES.COMPANY.DASHBOARD.PATH);
        break;
      case "ADMIN":
        navigate(ROUTES.ADMIN.DASHBOARD.PATH);
        break;
      default:
        // 处理未知用户类型,比如跳转到登录页或错误页
        navigate(ROUTES.DEFAULT.PATH);
    }
  } else {
    navigate(ROUTES.DEFAULT.PATH);
  }
};

2. 避免重复跳转,检查当前路由

跳转前先判断当前是否已经处于目标路由,防止重复调用navigate触发渲染:
首先引入useLocation:

import { useNavigate, useLocation } from "react-router-dom";

然后在组件中获取当前路径:

const location = useLocation();

修改redirectToDashboard:

const redirectToDashboard = () => {
  if (isLoggedIn) {
    let targetPath;
    switch(userDetails?.userType) {
      case "CANDIDATE":
        targetPath = ROUTES.CANDIDATE.DASHBOARD.PATH;
        break;
      case "COMPANY":
        targetPath = ROUTES.COMPANY.DASHBOARD.PATH;
        break;
      case "ADMIN":
        targetPath = ROUTES.ADMIN.DASHBOARD.PATH;
        break;
      default:
        targetPath = ROUTES.DEFAULT.PATH;
    }
    // 只有当前路径和目标路径不同时才跳转
    if (location.pathname !== targetPath) {
      navigate(targetPath);
    }
  } else {
    const targetPath = ROUTES.DEFAULT.PATH;
    if (location.pathname !== targetPath) {
      navigate(targetPath);
    }
  }
};

3. 优化依赖数组,消除ESLint警告

用useCallback包裹redirectToDashboard,确保函数引用稳定,同时把所有依赖加入useEffect的依赖数组:

import { useEffect, useCallback } from "react";

修改函数定义:

const redirectToDashboard = useCallback(() => {
  // ... 上面的逻辑
}, [isLoggedIn, userDetails, location, navigate, ROUTES]);

然后修改useEffect:

useEffect(() => {
  redirectToDashboard();
}, [redirectToDashboard]);

4. 检查路由配置

确认目标路由(比如ROUTES.CANDIDATE.DASHBOARD.PATH等)对应的组件没有重定向回Landing组件,确保路由跳转能正常完成。

最终修复后的代码

import { Spin } from "antd";
import { useEffect, useCallback } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import { ROUTES } from "./Common/Constants";

const Landing = () => {
  const isLoggedIn = !!localStorage.getItem("authToken");
  const userDetails = JSON.parse(localStorage.getItem("userDetails"));
  const navigate = useNavigate();
  const location = useLocation();

  const redirectToDashboard = useCallback(() => {
    if (isLoggedIn) {
      let targetPath;
      switch(userDetails?.userType) {
        case "CANDIDATE":
          targetPath = ROUTES.CANDIDATE.DASHBOARD.PATH;
          break;
        case "COMPANY":
          targetPath = ROUTES.COMPANY.DASHBOARD.PATH;
          break;
        case "ADMIN":
          targetPath = ROUTES.ADMIN.DASHBOARD.PATH;
          break;
        default:
          targetPath = ROUTES.DEFAULT.PATH;
      }
      if (location.pathname !== targetPath) {
        navigate(targetPath);
      }
    } else {
      const targetPath = ROUTES.DEFAULT.PATH;
      if (location.pathname !== targetPath) {
        navigate(targetPath);
      }
    }
  }, [isLoggedIn, userDetails, location, navigate, ROUTES]);

  useEffect(() => {
    redirectToDashboard();
  }, [redirectToDashboard]);

  return <Spin fullscreen size="large" />;
};

export default Landing;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 19:02:08