React导航栏点击链接页面冻结,疑似无限循环问题求助
问题分析与修复方案
核心问题(导致页面冻结/无限循环)
categories数组的引用变化:你在组件内部定义了categories数组,每次组件渲染时都会生成新的数组引用,导致监听categories的useEffect反复执行,不断触发组件动态导入,进而引发重渲染循环。- 内联函数引发的路由重复渲染:
renderPageComponent是组件内的内联函数,每次渲染都会重新创建,导致Route的element属性频繁变化,触发路由组件重复渲染。 - 冗余状态触发额外重渲染:
pageIndex状态在代码中没有实际用途,但每次路由变化都会更新它,增加了不必要的重渲染触发点。
修复后的完整代码
// NavBar.js import React, { Suspense } from 'react'; import { AppBar, Drawer, Toolbar, Typography, List, ListItem, ListItemText, ListSubheader } from '@material-ui/core'; import { Link, Route, Routes, useLocation } from 'react-router-dom'; // 将categories移到组件外部,确保引用稳定 const categories = [ { id: 0, title: 'Sales', pages: [ { id: 1, name: 'Sales 1', path: '/sales1', component: React.lazy(() => import('./path/to/Sales1')) }, { id: 2, name: 'Sales 2', path: '/sales2', component: React.lazy(() => import('./path/to/Sales2')) }, ], }, { id: 1, title: 'Marketing', pages: [ { id: 3, name: 'Marketing 1', path: '/marketing1', component: React.lazy(() => import('./path/to/Marketing1')) }, { id: 4, name: 'Marketing 2', path: '/marketing2', component: React.lazy(() => import('./path/to/Marketing2')) }, ], }, // 按需添加更多分类和页面 ]; const NavBar = () => { // 直接通过useLocation获取当前路径 const { pathname } = useLocation(); return ( <div> <AppBar> <Toolbar> <Typography variant="h6">系统导航</Typography> </Toolbar> </AppBar> <Drawer variant="permanent"> <List> {categories.map(category => ( <div key={category.id}> <ListSubheader>{category.title}</ListSubheader> {category.pages.map(page => ( <ListItem key={page.id} component={Link} to={page.path} button // 匹配当前路径,实现菜单项高亮(包括刷新页面场景) selected={pathname === page.path} > <ListItemText primary={`${page.id}. ${page.name}`} /> </ListItem> ))} </div> ))} </List> </Drawer> {/* 用Suspense包裹路由,处理动态组件加载时的过渡状态 */} <Suspense fallback={<div>加载中...</div>}> <Routes> {categories.flatMap(category => category.pages).map(page => ( <Route key={page.id} path={page.path} element={<page.component />} /> ))} </Routes> </Suspense> </div> ); }; export default NavBar;
关键修复点说明
categories移到组件外部:确保数组引用稳定,避免触发不必要的useEffect执行。- 使用
React.lazy动态导入组件:替代手动异步导入,符合React规范,配合Suspense处理组件加载过渡。 - 移除冗余状态:删除无用的
pageIndex及对应useEffect,减少重渲染触发源。 - 简化路径获取:直接用
useLocation的pathname,替代useResolvedPath,代码更简洁。 - 避免内联函数引发的路由更新:直接在
Route的element中渲染组件,无需额外渲染函数,避免函数重复创建导致的路由重复渲染。
内容的提问来源于stack exchange,提问作者Sreekanta B S V
相关产品推荐
相关产品推荐

