React问题:子组件无法更新父组件状态(MUI Modal场景)
问题分析与解决方案
嘿,我看了你的代码,马上就发现问题出在事件冒泡上!
你把<ActionModal>直接放在了父组件的<button>标签里面,当你点击Modal里的Cancel按钮时,虽然handleClose确实触发把modalOpen改成了false,但这个点击事件会顺着DOM往上冒泡,最终触发父组件button的onClick(也就是handleModalOpen),结果刚关掉Modal又立刻打开了,看起来就像Cancel按钮没生效一样。
下面给你两个简单的解决办法:
方法1:阻止Button组件的事件冒泡
修改你的Button组件,在点击事件里加上e.stopPropagation(),阻止事件向上传递:
const Button=(props)=>{ const {color,onClick,icon,name}=props; return <div className={styles.container} style={{background:color}} onClick={(e)=>{ e.stopPropagation(); // 阻止事件冒泡 onClick(); }}> {icon} <span>{name}</span> </div> }
方法2:把Modal移出触发按钮的DOM范围
其实MUI的Modal组件本身会被挂载到页面的顶层(默认是document.body),根本不需要放在触发它的button里面。把<ActionModal>移到父组件的button外面,这样点击Modal里的按钮就不会触发父按钮的点击事件了:
const TableIcon = props => { const {title,icon}=props; const [modalOpen, setModalOpen] = useState(false); const handleModalOpen = () => { setModalOpen(true); }; const handleModalClose = () => { setModalOpen(false); }; console.log('modal', modalOpen) return ( <> <button className={styles.button} title={title} onClick={handleModalOpen}> {icon} </button> {/* 把Modal移到button外面 */} <ActionModal open={modalOpen} handleClose={handleModalClose} handleOpen={handleModalOpen} /> </> ) }
个人更推荐方法2,因为这样的DOM结构更合理,Modal本来就不属于触发按钮的子元素,而且还能避免其他潜在的事件冒泡问题。
内容的提问来源于stack exchange,提问作者Sherif
相关产品推荐
相关产品推荐

