React中stopPropagation()失效求助:点击模态框仍触发关闭逻辑
问题分析与解决方案
我来帮你搞定这个模态框的冒泡问题!咱们先拆解下问题出在哪,再一步步修复:
1. 首先修复Modal组件的props接收问题
你的Modal组件定义时没声明接收props参数,这会导致props.toggle和props.children根本拿不到值,先把这个基础问题补上:
const Modal = (props) => { // 这里必须加上props参数 return ( <div className="modal__wrapper" onClick={props.toggle}> <div className="modal p-3"> <div className="modal__close" onClick={props.toggle} role="button" aria-hidden="true"> X </div> {props.children} </div> </div> ) }
2. 事件冒泡的阻止时机错了
你现在把stopPropagation()写在toggleModal函数里,但这个函数是绑定在外层遮罩wrapper上的——当你点击模态框内部时,事件已经冒泡到wrapper才触发这个函数,这时候再阻止冒泡完全没用,因为事件已经到达目标处理函数了。
正确的做法是:在模态框本身的容器div上添加点击事件,直接阻止事件冒泡到外层遮罩,这样点击模态框内部时,就不会触发遮罩的关闭逻辑:
修改后的Modal组件:
const Modal = (props) => { // 专门用来阻止模态框内部事件冒泡的函数 const stopModalBubble = (e) => { e.stopPropagation(); } return ( <div className="modal__wrapper" onClick={props.toggle}> {/* 给模态框容器加上阻止冒泡的事件 */} <div className="modal p-3" onClick={stopModalBubble}> <div className="modal__close" onClick={props.toggle} role="button" aria-hidden="true"> X </div> {props.children} </div> </div> ) }
嫌麻烦的话也可以直接内联写,效果一样:
<div className="modal p-3" onClick={(e) => e.stopPropagation()}>
3. 简化Footer组件的toggle函数
现在既然已经在模态框内部阻止了冒泡,toggleModal里的e.stopPropagation()就没必要留着了,可以简化成:
const Footer = () => { const [showModal, setShowModal] = useState(false); function toggleModal() { setShowModal(!showModal); } return ( <div> <button onClick={toggleModal}>Modal toggle</button> <Modal show={showModal} toggle={toggleModal}>This is a modal</Modal> </div> ) }
这样修改后,点击模态框内部区域就不会触发关闭,只有点击外层遮罩或者右上角的关闭按钮时,才会切换模态框的显示状态。
内容的提问来源于stack exchange,提问作者Jake
相关产品推荐
相关产品推荐

