Material UI Menu右键点击外部无法关闭的解决方案咨询
Great question! I’ve run into this exact behavior with Material-UI’s Menu and Dialog components before. The short answer is: there’s no built-in prop to enable right-click outside closing, but you can implement it easily with custom event listeners and a ref to track the component’s DOM element.
Why This Happens
By default, Material-UI’s overlay components (Menu, Dialog) use a ClickAwayListener that only reacts to left-click events (where MouseEvent.button === 0). Right-clicks (button 2) are ignored in the default logic, which is why your onClose doesn’t fire when right-clicking outside.
Solution 1: Custom Global Event Listener (Class Component)
Since you’re using a class component (evident from this.state and this.pageMenuOpen), here’s how to add right-click outside detection:
- First, create a ref to your Menu component:
constructor(props) { super(props); this.menuRef = React.createRef(); // ... rest of your constructor logic }
- Attach the ref to your Menu:
<Menu ref={this.menuRef} id="simple-menu" anchorReference="anchorPosition" anchorPosition={{top: this.state.pageMenu.y, left: this.state.pageMenu.x}} open={this.state.pageMenu.open} onClose={this.pageMenuClose} > {/* Your menu items here */} </Menu>
- Modify your
pageMenuOpento add a global mousedown listener, andpageMenuCloseto remove it:
pageMenuOpen = (event) => { this.setState({ pageMenu: { open: true, x: event.clientX, y: event.clientY } }); // Add listener for right-click outside document.addEventListener('mousedown', this.handleRightClickClose); }; pageMenuClose = () => { this.setState({ pageMenu: { ...this.state.pageMenu, open: false } }); // Clean up the listener to avoid memory leaks document.removeEventListener('mousedown', this.handleRightClickClose); };
- Add the handler to detect right-clicks outside the menu:
handleRightClickClose = (event) => { // Check if it's a right-click (button 2) and click is outside the menu if (event.button === 2 && this.menuRef.current) { const isClickInsideMenu = this.menuRef.current.contains(event.target); if (!isClickInsideMenu) { this.pageMenuClose(); // Optional: Prevent browser's default right-click menu from showing event.preventDefault(); } } };
Solution 2: Use ClickAwayListener (MUI v5+)
If you’re using Material-UI v5, you can wrap your Menu/Dialog in a custom ClickAwayListener that reacts to all mouse buttons:
import ClickAwayListener from '@mui/material/ClickAwayListener'; // Inside your render method <ClickAwayListener onClickAway={(event) => { // Trigger close on right-click outside if (event.button === 2) { this.pageMenuClose(); } }} > <Menu ref={this.menuRef} id="simple-menu" anchorReference="anchorPosition" anchorPosition={{top: this.state.pageMenu.y, left: this.state.pageMenu.x}} open={this.state.pageMenu.open} onClose={this.pageMenuClose} > {/* Your menu items */} </Menu> </ClickAwayListener>
Note: The default Menu already uses a ClickAwayListener, but adding this outer one will catch right-clicks that the internal one misses.
For Dialog Components
The exact same logic applies to Dialogs. Just attach a ref to your Dialog component, add the global mousedown listener when the Dialog opens, and check if right-clicks are outside the Dialog’s DOM element in your handler.
Key Notes
- Always clean up event listeners when the component unmounts or the menu/dialog closes to avoid memory leaks.
- If you don’t want the browser’s default right-click menu to appear when clicking outside, add
event.preventDefault()in your handler.
内容的提问来源于stack exchange,提问作者Stelium

