React.js中滚动隐藏Modal的优化问题求助
解决滚动隐藏Modal的问题
你的核心问题是useEffect依赖为空数组,仅在组件挂载时执行一次:如果初始popup为false,就不会添加滚动监听器;后续popup变为true时,useEffect不会重新触发,自然无法绑定监听器,导致Modal不能随滚动隐藏。
要同时满足「仅执行一次事件绑定」和「仅在Modal打开时触发隐藏逻辑」的要求,有两种可行方案:
方案1:用useRef同步最新状态,仅绑定一次监听器
通过useRef保存popup的最新值,无需修改useEffect的依赖,仅在组件挂载时绑定一次滚动监听器,每次滚动时检查最新的popup状态:
import { useEffect, useRef } from 'react'; // ... 其他组件代码 const popupRef = useRef(popup); // 同步popup状态到ref useEffect(() => { popupRef.current = popup; }, [popup]); // 仅挂载时绑定一次滚动监听器 useEffect(() => { const handleScroll = () => { // 仅在Modal打开时执行隐藏逻辑 if (popupRef.current) { selectEntryGroup(undefined); console.log("FIRED!"); } }; window.addEventListener('scroll', handleScroll); return () => { window.removeEventListener('scroll', handleScroll); // 组件卸载时清理监听器 }; }, []); // 依赖为空数组,确保仅执行一次
方案2:将popup加入依赖,动态更新监听器
把popup加入useEffect的依赖数组,当popup变化时,自动移除旧监听器并绑定新的,确保回调能获取到最新的popup状态:
import { useEffect } from 'react'; // ... 其他组件代码 useEffect(() => { const handleScroll = () => { if (popup) { selectEntryGroup(undefined); console.log("FIRED!"); } }; window.addEventListener('scroll', handleScroll); return () => { window.removeEventListener('scroll', handleScroll); }; }, [popup]); // 依赖popup,状态变化时更新监听器
这个方案代码更简洁,虽会在popup变化时重新绑定监听器,但性能影响可忽略不计。
两种方案都能满足代码评审要求:既避免了Modal未打开时触发无效滚动逻辑,又保证了事件绑定的合理性(方案1严格仅执行一次绑定,方案2逻辑清晰易维护)。
内容的提问来源于stack exchange,提问作者Eric sanchez
相关产品推荐
相关产品推荐

