二次使用侧边栏下拉导航触发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
相关产品推荐
相关产品推荐

