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

react-multilevel-dropdown点击子菜单父Dropdown关闭问题求助

react-multilevel-dropdown多级菜单点击父项时父级Dropdown自动关闭的解决方法

问题描述

使用react-multilevel-dropdown组件实现带二级子菜单的导航,希望同时支持点击父项显示子菜单(补充原悬停触发逻辑),但点击带二级菜单的父项时,父级的StyledDropdown会自动关闭,即使在切换子菜单的函数中添加了e.stopPropagation()和e.preventDefault()也无法阻止。

现有代码

Styled组件与切换函数

const StyledSubmenu = styled(Dropdown.Submenu)`
    display: ${props => (props.open ? "block" : "none")};
    margin-right: 2.5%;
    margin-top: 2.5%;
`;

function toggleSubmenu(e) {
    e.preventDefault();
    e.stopPropagation();
    setSubmenuOpen(!submenuOpen);
    if(submenuOpen2 === true){
        setSubmenuOpen2(!submenuOpen2);
    }
}

function toggleSubMenu2(e){
    e.preventDefault();
    e.stopPropagation();
    setSubmenuOpen2(!submenuOpen2);
    if(submenuOpen === true){
        setSubmenuOpen(!submenuOpen);
    }
}

组件渲染代码

<StyledDropdown title={<i className="fa fa-sm fa-bars"></i>}>
    <StyledItem onClick={(e) => toggleSubmenu(e)}>
        <i className='fa fa-sm fa-arrow-left me-2'></i>Cadastro
        <StyledSubmenu open={submenuOpen}>
            <StyledItem onClick={(e) => navigate('/estoque')}> Produtos </StyledItem>
            <StyledItem onClick={(e) => navigate('/grp-consultar')}> Grupos </StyledItem>
            <StyledItem onClick={(e) => navigate('/mar-consultar')}> Marcas  </StyledItem>
            <StyledItem onClick={(e) => navigate('/loc-consultar')}> Localizações</StyledItem>
            <StyledItem onClick={(e) => navigate('/uni-consultar')}> Unidades </StyledItem>
            <StyledItem onClick={(e) => navigate('/cat-consultar')}> Categorias </StyledItem>
            <StyledItem onClick={(e) => navigate('/tgr-consultar')}> Tipos de Grade </StyledItem>
        </StyledSubmenu>
    </StyledItem>
    <StyledItem onClick={(e) => toggleSubMenu2(e)}>
        <i className='fa fa-sm fa-arrow-left me-2'></i> Movimento
        <StyledSubmenu open={submenuOpen2}>
            <StyledItem onClick={(e) => navigate('/sub-grupo-1')}> Movimento do Produto </StyledItem>
            <StyledItem onClick={(e) => navigate('/sub-grupo-2')}> Controle de Produção </StyledItem>
            <StyledItem onClick={(e) => navigate('/sub-grupo-3')}> Balanço de Estoque </StyledItem>
            <StyledItem onClick={(e) => navigate('/sub-grupo-4')}> Acerto de Estoque </StyledItem>
        </StyledSubmenu>
    </StyledItem>
</StyledDropdown>

解决方案

1. 禁用父级Dropdown的点击关闭行为

react-multilevel-dropdown通常提供closeOnClick属性,设置为false可阻止父级Dropdown在点击内部项时自动关闭:

<StyledDropdown 
  title={<i className="fa fa-sm fa-bars"></i>}
  closeOnClick={false}
>
  {/* 子项内容 */}
</StyledDropdown>

2. 改用受控模式控制父级Dropdown显隐

如果组件支持受控模式,通过state手动控制父级Dropdown的打开状态,避免其自动触发关闭:

import { useState } from 'react';

// 新增父级Dropdown状态
const [dropdownOpen, setDropdownOpen] = useState(false);

const toggleDropdown = () => {
  setDropdownOpen(!dropdownOpen);
};

// 渲染时使用受控属性
<StyledDropdown 
  title={<i className="fa fa-sm fa-bars"></i>}
  open={dropdownOpen}
  onToggle={toggleDropdown}
>
  {/* 子项内容 */}
</StyledDropdown>

3. 替换点击事件为mousedown事件

mousedown事件触发时机早于Dropdown内部的关闭监听事件,改用该事件可阻止冒泡被Dropdown的关闭逻辑拦截:

<StyledItem onMouseDown={(e) => toggleSubmenu(e)}>
  <i className='fa fa-sm fa-arrow-left me-2'></i>Cadastro
  {/* 子菜单 */}
</StyledItem>

4. 检查StyledItem的样式配置

确保StyledItem没有设置pointer-events: none等会阻断事件传递的样式,避免事件无法正确触发或冒泡。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:20:57