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

二次使用侧边栏下拉导航触发Maximum update depth exceeded错误排查

解决React侧边栏下拉菜单跳转的无限渲染问题

问题现象

首次点击下拉选项跳转正常,但再次点击同一或其他选项时,控制台抛出:

Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.

同时按钮从DOM中消失,下拉菜单变为空。

问题原因

核心问题出在DropdownItem组件的状态逻辑上:

  • 点击按钮触发setGoTo(true),组件返回<Navigate>组件触发路由跳转
  • 路由跳转后,当前页面的组件重新渲染,但DropdownItem的goTo状态仍为true,会持续返回<Navigate>组件
  • 这导致路由反复跳转,触发无限的组件更新循环,最终抛出深度超限警告,原按钮被替换后看起来像是消失

解决方案

方案一:用useNavigate钩子直接处理跳转(推荐)

抛弃状态控制逻辑,直接使用React Router的useNavigate钩子实现跳转,从根源避免循环:

import { useNavigate } from 'react-router-dom';

const DropdownItem = (props) => {
  const navigate = useNavigate();

  return (
    <div className="...">
      <button
        onClick={() => navigate(props.itemLink)}
        className="..."
      >
        {props.itemName}
      </button>
    </div>
  );
};

方案二:路由跳转后重置状态(不推荐,仅作参考)

如果必须保留状态逻辑,可监听路由变化重置goTo状态:

import { Navigate, useLocation } from 'react-router-dom';
import { useEffect, useState } from 'react';

const DropdownItem = (props) => {
  const [goTo, setGoTo] = useState(false);
  const location = useLocation();

  useEffect(() => {
    // 路由变化后重置状态,避免持续触发跳转
    setGoTo(false);
  }, [location]);

  if (goTo) {
    return <Navigate exact to={props.itemLink} />;
  }

  return (
    <div className="...">
      <button
        onClick={() => setGoTo(true)}
        className="..."
      >
        {props.itemName}
      </button>
    </div>
  );
};

额外优化:简化下拉项生成逻辑

用map替代for循环,让代码更简洁,同时添加key属性避免React列表渲染警告:

// SidenavDropdown中生成下拉项
const rows = props.sidenavItemNames.map((name, index) => (
  <DropdownItem
    key={index}
    itemName={name}
    itemLink={props.sidenavItemLinks[index]}
  />
));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 12:52:19