React项目中MUI ClickAwayListener点击自定义Modal组件自身时误触发关闭的问题求助
我明白你的问题了——你用MUI的ClickAwayListener配合自定义的styled-components模态框,结果点击模态框内部也会触发关闭,这显然不符合预期。问题出在ClickAwayListener默认的判断逻辑无法正确识别你的自定义模态框属于内部元素,不过我们可以通过添加DOM引用(ref)来手动判断点击目标是否在模态框内,从而解决这个问题。
解决方案步骤
- 创建一个ref来获取模态框的DOM元素
- 在
handleClickAway函数中检查点击目标是否属于模态框内部,如果是则不执行关闭操作 - 移除原来不必要的
body判断逻辑
修改后的完整代码
import { useRef, useState } from 'react'; import { ClickAwayListener } from '@mui/material'; import styled from 'styled-components'; const Modal = styled.div` position: absolute; top: 30px; left: -200px; background: #fff; padding: 25px; z-index: 8; visibility: ${({ visible }) => (visible ? 'visible' : 'hidden')}; box-shadow: 0px 3px 15px rgba(0, 0, 0, 0.2); width: 250px; max-height: 320px; overflow-y: auto; `; const YourComponent = () => { const [modalVisible, setModalVisible] = useState(false); const modalRef = useRef<HTMLDivElement>(null); // 创建模态框的ref const dummy = ['Item 1', 'Item 2', 'Item 3']; // 示例数据 const handleClickAway = (e: MouseEvent) => { // 检查点击目标是否在模态框内部,若是则不关闭 if (modalRef.current && modalRef.current.contains(e.target as Node)) { return; } setModalVisible(false); }; return ( <ClickAwayListener onClickAway={handleClickAway}> <div style={{ position: 'relative' }}> <button onClick={(e) => { e.stopPropagation(); setModalVisible(!modalVisible); }} > More </button> {/* 将ref传递给自定义模态框 */} <Modal ref={modalRef} visible={modalVisible} id="btn-container"> {dummy.map((str, index) => ( <span key={index}>{str}</span> ))} </Modal> </div> </ClickAwayListener> ); }; export default YourComponent;
原理说明
useRef用来获取模态框的真实DOM元素,这样我们可以用contains()方法判断点击事件的目标是否属于模态框内部。- 当点击模态框内部时,
handleClickAway会直接返回,不执行关闭逻辑;只有点击模态框以外的区域(包括More按钮、页面其他地方)才会关闭模态框,完全符合你的需求。 - 保留了
e.stopPropagation()在按钮的点击事件中,防止点击按钮时触发ClickAwayListener的逻辑,确保按钮的toggle功能正常。
内容的提问来源于stack exchange,提问作者Hardik Aswal
相关产品推荐
相关产品推荐

