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

如何以编程方式关闭Material-UI DropDownMenu?点击不闭合问题

解决Material-UI DropDownMenu点击NavLink项后无法关闭的问题

问题的核心是你目前的closeMenu仅打印日志,没有实际触发DropDownMenu的关闭逻辑。针对老版本Material-UI的DropDownMenu组件,我们可以通过获取组件引用并调用内部关闭方法来解决这个问题,具体实现步骤如下:

步骤1:给DropDownMenu添加Ref引用

首先在组件内部创建一个Ref,用来获取DropDownMenu的实例,方便后续调用它的内部方法:

class QuickMenu extends React.Component {
  constructor(props) {
    super(props);
    // 创建Ref存储下拉菜单实例
    this.dropdownRef = React.createRef();
  }
  // ... 其他原有代码
}

然后在render方法中给DropDownMenu绑定这个Ref:

<DropdownMenu
  ref={this.dropdownRef}
  value={defaultSelection}
  className="quick-dropdown"
>
  {this.renderMenuItems()}
</DropdownMenu>

步骤2:实现真正的菜单关闭逻辑

修改closeMenu函数,通过Ref调用DropDownMenu内部的handleClose()方法(这是组件原生的关闭逻辑):

const closeMenu = (dropdownRef) => {
  if (dropdownRef.current) {
    // 触发下拉菜单的关闭动作
    dropdownRef.current.handleClose();
    console.log('closeMenu...');
  }
};

步骤3:传递Ref到renderNavLink函数

在renderMenuItems中调用renderNavLink时,把组件的dropdownRef传递过去,确保关闭函数能拿到菜单实例:

renderMenuItems() {
  return menuItems.map((item, i) => {
    if (item.to) return renderNavLink(i, item, () => closeMenu(this.dropdownRef));
    return renderClickable(i, item, this.props);
  });
}

完整修改后的组件代码

/* eslint-disable react/no-array-index-key */
import React from 'react';
import { NavLink } from 'react-router-dom';
import { connect } from 'react-redux';
// Material UI Components
import { ToolbarGroup } from 'material-ui/Toolbar';
import DropdownMenu from 'material-ui/DropDownMenu';
import MenuItem from 'material-ui/MenuItem';
// Actions
import { closeModal, setModal } from 'actions/Modals';
// Styles
import { navLink } from 'components/Styles/material';
// Copy
import { MODAL_CREATEDRAFT_NAME } from 'copy';
// Utils
import { cleanMapStateToProps } from 'utils';

const menuItems = [{ primaryText: 'Quick Menu', className: 'quickmenu-navlink' }, { primaryText: 'Create Draft', className: 'quickmenu-navlink', modal: MODAL_CREATEDRAFT_NAME }, { primaryText: 'My Drafts', to: '/drafts/mine' }, { primaryText: 'Active Drafts', to: '/drafts/active' }, { primaryText: 'Archived Drafts', to: '/drafts/archived' }, { primaryText: 'Environment Status', to: '/drafts/environments' }];
const defaultSelection = menuItems[0].primaryText;

const renderNavLink = (i, { to, primaryText: value }, closeMenu) => (
  <NavLink key={i} to={to} style={navLink.default} onClick={closeMenu} >
    <MenuItem key={i} value={value}>
      {value}
    </MenuItem>
  </NavLink>
);

const renderClickable = (i, { modal, onClick, className, primaryText: value }, { setModal: setModalAction }) => (
  <MenuItem key={i} value={value} primaryText={value} style={navLink.special} className={className || ''} onClick={modal ? () => setModalAction(modal) : onClick} />
);

const closeMenu = (dropdownRef) => {
  if (dropdownRef.current) {
    dropdownRef.current.handleClose();
    console.log('closeMenu...');
  }
};

class QuickMenu extends React.Component {
  constructor(props) {
    super(props);
    this.dropdownRef = React.createRef();
  }

  componentWillReceiveProps(nextProps) {
    const { currentDraft } = nextProps;
    if (currentDraft && currentDraft.id) {
      this.props.closeModal();
    }
  }

  renderMenuItems() {
    return menuItems.map((item, i) => {
      if (item.to) return renderNavLink(i, item, () => closeMenu(this.dropdownRef));
      return renderClickable(i, item, this.props);
    });
  }

  render() {
    return (
      <ToolbarGroup>
        <DropdownMenu
          ref={this.dropdownRef}
          value={defaultSelection}
          className="quick-dropdown"
        >
          {this.renderMenuItems()}
        </DropdownMenu>
      </ToolbarGroup>
    );
  }
}

export const QuickMenuJest = QuickMenu;

const mapDispatchToProps = dispatch => ({
  closeModal: (...args) => {
    dispatch(closeModal(...args));
  },
  setModal: (...args) => {
    dispatch(setModal(...args));
  }
});

export default connect(cleanMapStateToProps(['location', 'currentDraft']), mapDispatchToProps)(QuickMenu);

兼容老版本React的补充说明

如果你的项目使用的是不支持React.createRef()的老版本React,可以换成回调式Ref:

// 替换constructor里的Ref创建
// this.dropdownRef = React.createRef();

// 在render的DropDownMenu中使用回调Ref
<DropdownMenu
  ref={(ref) => { this.dropdownRef = ref; }}
  value={defaultSelection}
  className="quick-dropdown"
>

同时修改closeMenu函数:

const closeMenu = (dropdownRef) => {
  if (dropdownRef) {
    dropdownRef.handleClose();
    console.log('closeMenu...');
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:30:34