我有一个带有自定义MenuItems的Material UI菜单组件。现在,当菜单和子菜单打开时,我希望能够在菜单外部单击时关闭整个菜单。我仍然需要单击两次,首先关闭子菜单,然后关闭实际菜单。
文档MUI menu涉及使用anchorEl
作为boolean
来确定菜单是否打开,但是即使我从自定义菜单项发送close回调函数,它也只能通过关闭自身来关闭在组件外部单击时的handleClose()
。因此,在所附图片中,仅关闭了包含公司财务的容器,而没有关闭菜单。
无法理解,由于anchorEl
在closeFunction
中变为null,因此核心菜单仍然保持打开状态。尝试使用基于Modal组件的menu和MenuItems和Popover。
MenuComponent
:
const MoreMenu = ({
userTagData,
onChangeItemName,
selectedTags,
onTagSelected,
onRemoveItem,
data,
item,
}) => {
const [anchorEl, setAnchorEl] = useState(null);
const [subMenuPopUpName, setSubMenuPopUpName] = useState('');
const renderChangeTitlePopUp = () => (
<ChangeTitleContainer
onChangeItemName={onChangeItemName}
closeMenuItem={handleClose}
item={item}
/>
);
const renderAddTagPopUp = () => (
<AddTagContainer
item={item}
userTagData={userTagData}
selectedTags={selectedTags}
onTagSelected={onTagSelected}
/>
);
const renderRemoveItemContainer = () => (
<RemoveItemContainer
item={item}
onRemoveItem={onRemoveItem}
closeMenuItem={handeleClose}
/>
);
const renderDefaultPopup = () => (
<div><p>Standard menu post</p></div>
);
const menuItemPopUpSwitcher = (name) => {
switch (name) {
case ADDTAG:
return renderAddTagPopUp();
case CHANGETITLE:
return renderChangeTitlePopUp();
case REMOVEITEM:
return renderRemoveItemContainer();
default:
return renderDefaultPopup();
}
};
const handleMenuItemClick = (item, event) => {
setAnchorEl(event.currentTarget);
setSubMenuPopUpName(item.title);
setAnchorEl(event.currentTarget);
menuItemPopUpSwitcher(item);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<Fragment>
<MoreButton
data={data}
handleMenuItemClick={handleMenuItemClick}
/>
<Menu
open={Boolean(anchorEl)}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'top',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
>
{menuItemPopUpSwitcher(subMenuPopUpName)}
</Menu>
</Fragment>
);
};custom
答案 0 :(得分:1)
能够通过为父锚添加另一个状态来解决问题。因此,父菜单具有其自己的锚,子菜单弹出其自身的锚,然后handleClose()禁用它们。请参见示例和5行标有///这是新的:
const MoreMenu = ({
userTagData,
onChangeItemName,
selectedTags,
onTagSelected,
onRemoveItem,
data,
item,
}) => {
const [parentAnchorEl, setParentAnchorEl] = useState(null); // THIS IS NEW
const [anchorEl, setAnchorEl] = useState(null);
const [subMenuPopUpName, setSubMenuPopUpName] = useState('');
const handleMoreButtonClick = (event) => { // THIS IS NEW
setParentAnchorEl(event.currentTarget);
};
const renderChangeTitlePopUp = () => (
<ChangeTitleContainer
onChangeItemName={onChangeItemName}
closeMenuItem={handleClose}
item={item}
/>
);
const renderAddTagPopUp = () => (
<AddTagContainer
item={item}
userTagData={userTagData}
selectedTags={selectedTags}
onTagSelected={onTagSelected}
/>
);
const renderRemoveItemContainer = () => (
<RemoveItemContainer
item={item}
onRemoveItem={onRemoveItem}
closeMenuItem={handeleClose}
/>
);
const renderDefaultPopup = () => (
<div><p>Standard menu post</p></div>
);
const menuItemPopUpSwitcher = (name) => {
switch (name) {
case ADDTAG:
return renderAddTagPopUp();
case CHANGETITLE:
return renderChangeTitlePopUp();
case REMOVEITEM:
return renderRemoveItemContainer();
default:
return renderDefaultPopup();
}
};
const handleMenuItemClick = (item, event) => {
setAnchorEl(event.currentTarget);
setSubMenuPopUpName(item.title);
setAnchorEl(event.currentTarget);
menuItemPopUpSwitcher(item);
};
const handleClose = () => {
setAnchorEl(null);
setParentAnchorEl(null); //THIS IS NEW
};
return (
<Fragment>
<MoreButton
anchorEl={parentAnchorEl} //THIS IS NEW
data={data}
handleMenuItemClick={handleMenuItemClick}
handleClick={handleMoreButtonClick} //THIS IS NEW
/>
<Menu
open={Boolean(anchorEl)}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'top',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
>
{menuItemPopUpSwitcher(subMenuPopUpName)}
</Menu>
</Fragment>
);
};custom