如何以编程方式关闭Material-UI DropDownMenu?点击不闭合问题
问题的核心是你目前的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
相关产品推荐
相关产品推荐

