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

React Web应用中MUI Drawer组件可打开无法关闭如何解决

问题根因

Drawer无法关闭的核心原因是事件冒泡冲突,附带几个小的代码问题:

  • 你把<Drawer>组件直接写在了绑定了onClick={handleOpen}的.hamburger容器内部。当点击遮罩层、或者侧边栏内链接触发handleClose把drwOpen设为false时,点击事件会顺着DOM树冒泡到父级.hamburger元素,立刻触发handleOpen把drwOpen重新设为true,视觉上就表现为Drawer完全关不上。
  • 侧边栏的关闭事件只绑定在了.menu父容器上,点击侧边栏内非.menu区域不会触发关闭,逻辑鲁棒性不足。
  • 额外语法问题:Sidebar里写了无效标签<pXYZ>,Navbar里存在多余的闭合标签、未使用的导入,会导致渲染/编译异常。
修复方案
  1. 将<Drawer>组件移出.hamburger点击容器,放到和导航栏其他元素平级的位置,彻底阻断事件冒泡导致的状态反复。
  2. 调整侧边栏关闭逻辑,给每个导航项单独绑定点击关闭事件,避免事件冒泡异常导致关闭失效。
  3. 清理无效标签、无用导入、多余DOM闭合标签。

修复后代码

import React, { useState } from "react";
import "./navbar.css";
import Sidebar from "./Sidebar";
import { NavLink } from "react-router-dom";
import { Drawer } from "@mui/material";
import IconButton from "@mui/material/IconButton";
import MenuIcon from "@mui/icons-material/Menu";

const Navbar = () => {
  const [drwOpen, setDrwOpen] = useState(false);

  const handleOpen = () => {
    setDrwOpen(true);
  };
  const handleClose = () => {
    setDrwOpen(false);
  };

  return (
    <header>
      <nav>
        <div className="left">
          <div className="hamburger" onClick={handleOpen}>
            <IconButton>
              <MenuIcon style={{ color: "#fff" }} fontSize="large" />
            </IconButton>
          </div>
          {/* Drawer移出点击容器,和.hamburger平级 */}
          <Drawer open={drwOpen} onClose={handleClose}>
            <Sidebar logClose={handleClose}/>
          </Drawer>

          <NavLink to="/">
            <img
              className="navlogo"
              src={process.env.PUBLIC_URL + "/math.png"}
              alt="logo"
            />
          </NavLink>
        </div>
      </nav>
    </header>
  );
};

export default Navbar;
import React from "react";
import { NavLink } from "react-router-dom";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import "./sidebar.css";

const Sidebar = ({logClose}) => {
  return (
    <div className="sidebar">
      <p>random text</p>
      <div className="menu">
        {/* 每个导航项单独绑定关闭事件 */}
        <NavLink to="/" style={{ textDecoration: "none" }} className="lis" onClick={logClose}>
          <p>ABC</p>
          <ChevronRightIcon style={{ fill: "#949494" }}/>
        </NavLink>

        <NavLink to="/xyz" style={{ textDecoration: "none" }} className="lis" onClick={logClose}>
          {/* 修正无效标签 */}
          <p>XYZ</p>
          <ChevronRightIcon style={{ fill: "#949494" }}/>
        </NavLink>

        <NavLink to="/123" style={{ textDecoration: "none" }} className="lis" onClick={logClose}>
          <p>123</p>
          <ChevronRightIcon style={{ fill: "#949494" }}/>
        </NavLink>
      </div>
    </div>
  );
};

export default Sidebar;

补充说明:MUI Drawer自带的onClose属性本身就会处理点击遮罩层、按ESC键的关闭逻辑,只要没有事件冒泡干扰,不需要额外编写遮罩层的关闭监听。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:33:40