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

Next.js中使用Material UI Collapse组件构建汉堡菜单报错求助

问题分析与修复方案

1. Collapse组件导入错误

你的代码里Collapse的导入方式完全错误:

import Collapse from "@mui/material";

MUI的组件需要从具体的组件路径导入,正确的导入应该是:

import Collapse from "@mui/material/Collapse";

直接导入@mui/material会拿到整个包的导出对象,而非Collapse组件本身,这是导致报错的核心原因。

2. 全局状态导致所有子菜单同步展开

当前用单个open状态控制所有带submenu的项,点击任何一个子菜单按钮,所有子菜单都会同时展开/收起。需要给每个子菜单单独维护状态,比如用对象记录每个菜单标题的展开状态:

const [openMenus, setOpenMenus] = useState({});

const handleClick = (title) => {
  setOpenMenus(prev => ({
    ...prev,
    [title]: !prev[title]
  }));
};

3. List组件嵌套结构错误

  • 子菜单里ListItemButton嵌套ListItem是冗余且错误的结构,MUI中ListItemButton本身就是可交互的列表项容器,直接在里面放置ListItemText即可。
  • 非子菜单项里错误地把ListItemText放在ListItemIcon内部,ListItemIcon是用来放图标的容器,文本应该和它同级放置。

修复后的完整代码

import * as React from "react";
import { useState } from "react";
import IconButton from "@mui/material/IconButton";
import ListSubheader from "@mui/material/ListSubheader";
import { Drawer } from "@mui/material";
import List from "@mui/material/List";
import ListItemButton from "@mui/material/ListItemButton";
import ListItemIcon from "@mui/material/ListItemIcon";
import ListItemText from "@mui/material/ListItemText";
import MenuIcon from "@mui/icons-material/Menu";
import { ExpandLess, ExpandMore } from "@mui/icons-material";
import Collapse from "@mui/material/Collapse";

const myMenu = [
  { title: "about" },
  {
    title: "services",
    submenu: [{ title: "Digital Marketing" }, { title: "Promotion" }],
  },
  { title: "blog" },
  { title: "contact" },
];

const ResponsiveAppBar = () => {
  const [openDrawer, setOpenDrawer] = useState(false);
  // 用对象记录每个菜单的展开状态
  const [openMenus, setOpenMenus] = useState({});

  const handleClick = (title) => {
    setOpenMenus((prev) => ({
      ...prev,
      [title]: !prev[title],
    }));
  };

  return (
    <React.Fragment>
      <Drawer
        anchor="right"
        open={openDrawer}
        onClose={() => setOpenDrawer(false)}
      >
        <List
          sx={{ width: "100%", maxWidth: 360, bgcolor: "background.paper" }}
          component="nav"
          aria-labelledby="nested-list-subheader"
          subheader={
            <ListSubheader component="div" id="nested-list-subheader">
              Navigation
            </ListSubheader>
          }
        >
          {myMenu.map((page, index) =>
            page.submenu ? (
              <div key={index}>
                <ListItemButton onClick={() => handleClick(page.title)}>
                  <ListItemText primary={page.title} />
                  {openMenus[page.title] ? <ExpandLess /> : <ExpandMore />}
                </ListItemButton>

                <Collapse
                  in={openMenus[page.title]}
                  timeout="auto"
                  unmountOnExit
                >
                  <List component="div" disablePadding>
                    {page.submenu.map((sub, subIndex) => (
                      <ListItemButton key={subIndex} sx={{ pl: 4 }}>
                        <ListItemText primary={sub.title} />
                      </ListItemButton>
                    ))}
                  </List>
                </Collapse>
              </div>
            ) : (
              <ListItemButton key={index}>
                {/* 这里可以添加对应图标,比如HomeIcon等 */}
                <ListItemIcon></ListItemIcon>
                <ListItemText primary={page.title} />
              </ListItemButton>
            )
          )}
        </List>
      </Drawer>
      <IconButton
        sx={{ color: "black", marginLeft: "auto" }}
        onClick={() => setOpenDrawer(!openDrawer)}
      >
        <MenuIcon color="white" />
      </IconButton>
    </React.Fragment>
  );
};

export default ResponsiveAppBar;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:20:04