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

React新手求助:如何用NavLink在Material UI导航栏实现三级子菜单

实现React三级导航子菜单(Report > My report > MIS report)

嘿,作为React新手,要实现三级嵌套子菜单其实不难,咱们一步步来搞定它!结合你用的react-router-dom和Material-UI组件,我给你整理了具体的实现方案:

1. 重构mainListItems为带状态的函数组件

原来的mainListItems是静态JSX,咱们需要把它改成能控制菜单展开/收起的函数组件,用React Hooks来管理状态。首先确保你已经安装了Material-UI的折叠组件(如果没装,执行npm install @mui/material @mui/icons-material即可)。

import React, { useState } from 'react';
import { List, ListItem, ListItemIcon, ListItemText, Collapse } from '@mui/material';
import { NavLink } from 'react-router-dom';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';

export const MainListItems = () => {
  // 控制一级菜单(Report)的展开状态
  const [isReportOpen, setIsReportOpen] = useState(false);
  // 控制二级菜单(My report)的展开状态
  const [isMyReportOpen, setIsMyReportOpen] = useState(false);

  const toggleReportMenu = () => {
    setIsReportOpen(!isReportOpen);
  };

  const toggleMyReportMenu = () => {
    setIsMyReportOpen(!isMyReportOpen);
  };

  return (
    <List>
      <NavLink to="/dashboard" style={{ textDecoration: 'none', color: 'inherit' }}>
        <ListItem button>
          <ListItemIcon></ListItemIcon>
          <ListItemText primary="Dashboard" />
        </ListItem>
      </NavLink>
      <NavLink to="/userform" style={{ textDecoration: 'none', color: 'inherit' }}>
        <ListItem button>
          <ListItemIcon></ListItemIcon>
          <ListItemText primary="Registration" />
        </ListItem>
      </NavLink>

      {/* 一级菜单:Report */}
      <ListItem button onClick={toggleReportMenu}>
        <ListItemIcon></ListItemIcon>
        <ListItemText primary="Report" />
        {isReportOpen ? <ExpandMoreIcon /> : <ChevronRightIcon />}
      </ListItem>
      <Collapse in={isReportOpen} timeout="auto" unmountOnExit>
        <List component="div" disablePadding>
          {/* 二级菜单:My report */}
          <ListItem button onClick={toggleMyReportMenu} sx={{ pl: 4 }}>
            <ListItemIcon></ListItemIcon>
            <ListItemText primary="My report" />
            {isMyReportOpen ? <ExpandMoreIcon /> : <ChevronRightIcon />}
          </ListItem>
          <Collapse in={isMyReportOpen} timeout="auto" unmountOnExit>
            <List component="div" disablePadding>
              {/* 三级菜单:MIS report */}
              <NavLink to="/report/my-report/mis-report" style={{ textDecoration: 'none', color: 'inherit' }}>
                <ListItem button sx={{ pl: 8 }}>
                  <ListItemIcon></ListItemIcon>
                  <ListItemText primary="MIS report" />
                </ListItem>
              </NavLink>
            </List>
          </Collapse>
        </List>
      </Collapse>
    </List>
  );
};

2. 更新路由配置(App.js)

接下来要给三级菜单对应的路径添加路由,记得先创建好MISReport组件(你可以根据业务需求编写这个组件的内容):

import React from 'react';
import { HashRouter, Switch, Route, Redirect } from 'react-router-dom';
import SignIn from './SignIn'; // 你的组件路径
import UserForm from './UserForm';
import Dashboard from './Dashboard';
import MISReport from './MISReport'; // 新增的MIS报告组件

const App = () => (
  <HashRouter>
    <Switch>
      <Route path="/signin" component={SignIn} />
      <Route path="/userform" component={UserForm} />
      <Route path="/dashboard" component={Dashboard} />
      {/* 新增三级菜单对应的路由 */}
      <Route path="/report/my-report/mis-report" component={MISReport} />
      <Redirect from="/" to="/signin" />
    </Switch>
  </HashRouter>
);

export default App;

3. 关键细节说明

  • 层级样式:用sx={{ pl: 4 }}和sx={{ pl: 8 }}给子菜单添加缩进,让层级关系更直观;给NavLink添加样式是为了去掉默认链接样式,保持菜单视觉统一。
  • 展开/收起逻辑:通过两个useState变量分别控制一、二级菜单的展开状态,点击菜单时触发状态切换。
  • 路由匹配:确保NavLink的to属性和路由配置的path完全对应,这样点击菜单才能正确跳转至目标页面。

这样你就能实现一个可展开收起的三级子菜单啦,测试一下:点击Report会展开My report,再点击My report就能看到MIS report,点击MIS report会跳转到对应的页面~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 23:12:39