React Web应用中MUI Drawer组件可打开无法关闭如何解决
问题根因
Drawer无法关闭的核心原因是事件冒泡冲突,附带几个小的代码问题:
- 你把
<Drawer>组件直接写在了绑定了onClick={handleOpen}的.hamburger容器内部。当点击遮罩层、或者侧边栏内链接触发handleClose把drwOpen设为false时,点击事件会顺着DOM树冒泡到父级.hamburger元素,立刻触发handleOpen把drwOpen重新设为true,视觉上就表现为Drawer完全关不上。 - 侧边栏的关闭事件只绑定在了
.menu父容器上,点击侧边栏内非.menu区域不会触发关闭,逻辑鲁棒性不足。 - 额外语法问题:Sidebar里写了无效标签
<pXYZ>,Navbar里存在多余的闭合标签、未使用的导入,会导致渲染/编译异常。
修复方案
- 将
<Drawer>组件移出.hamburger点击容器,放到和导航栏其他元素平级的位置,彻底阻断事件冒泡导致的状态反复。 - 调整侧边栏关闭逻辑,给每个导航项单独绑定点击关闭事件,避免事件冒泡异常导致关闭失效。
- 清理无效标签、无用导入、多余DOM闭合标签。
修复后代码
Navbar.js
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;
Sidebar.js
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
相关产品推荐
相关产品推荐

