升级至React 18后出现额外点击,菜单组件功能异常
解决React 18中菜单展开后立即关闭的问题
问题原因
点击菜单图标时,click事件会向父元素冒泡直至document.body。在React 17中,MenuBox是在点击事件处理完成后才完成渲染的,因此它的useEffect中添加的body点击监听器不会捕获到这次冒泡的事件。但React 18优化了同步更新的渲染时机,MenuBox会在同一事件循环内完成渲染,其useEffect回调会立即执行,此时body的点击事件仍在冒泡过程中,新绑定的监听器就会捕获到这次点击,触发菜单关闭逻辑。
解决方案
方案1:阻止菜单触发按钮的事件冒泡
在Menu组件的点击处理函数中,阻止事件继续冒泡到document.body:
function clicked(e) { console.log('DEBUG: Menu.jsx clicked') e.stopPropagation(); // 阻止事件向上冒泡 dispatch({type: 'toggleMenuPage'}); }
方案2:在body点击监听器中过滤点击源
修改MenuBox的useEffect,判断点击事件是否来自菜单内部或触发按钮,只有点击外部时才关闭菜单:
useEffect(() => { console.log('DEBUG: MenuBox.jsx useEffect()') function bodyClicked(e) { const menuContainer = document.getElementById('menu_hold'); // 若点击目标不在菜单容器内,才执行关闭逻辑 if (!menuContainer.contains(e.target)) { dispatch({type: 'toggleMenuPageOff'}); console.log('DEBUG: MenuBox.jsx useEffect(): bodyClicked()') } } document.body.addEventListener('click', bodyClicked); return () => { document.body.removeEventListener('click', bodyClicked); }; }, []); // 添加空依赖数组,确保监听器只绑定一次
内容的提问来源于stack exchange,提问作者k.m.
相关产品推荐
相关产品推荐

