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

React导航栏点击链接页面冻结,疑似无限循环问题求助

问题分析与修复方案

核心问题(导致页面冻结/无限循环)

  1. categories数组的引用变化:你在组件内部定义了categories数组,每次组件渲染时都会生成新的数组引用,导致监听categories的useEffect反复执行,不断触发组件动态导入,进而引发重渲染循环。
  2. 内联函数引发的路由重复渲染:renderPageComponent是组件内的内联函数,每次渲染都会重新创建,导致Route的element属性频繁变化,触发路由组件重复渲染。
  3. 冗余状态触发额外重渲染: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 09:28:14