本文主要是介绍addEventListener与useeffect相撞的火花,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
const [a, seta] = useState(1)
const [loading, setLoading] = useState(false) //用于等到某个异步操作返回结果后再允许再次触发fn函数useEffect(() => {document.addEventListener('LazShake.Event.onShakeOnce', () => {fn('listener');});}, []);useEffect(() => {setTimeout(() => {seta(2)},1000)},[])const fn = (from) => {if (loading) { return }setLoading(true);const time=new Date(Date.now())console.log(11111, 'from: ', from, "min: ",time.getMinutes(),"sec: ",time.getSeconds(), 'a: ',a);setTimeout(() => {setLoading(false)}, 2000)};
两种方式触发fn, 监听事件:addEventListener; 点击任意事件触发fn:click
发现:监听事件触发的fn,变量a不更新, loading参数不更新, 监听事件的fn为第一次渲染时候的快照,里面的参数后续不更新
如果将上述监听事件改为
const triggerFn = useCallback(() => {fn('listener');}, [a]);useEffect(() => {document.addEventListener('LazShake.Event.onShakeOnce', triggerFn);return () => {document.removeEventListener('LazShake.Event.onShakeOnce', triggerFn)}}, [triggerFn]);
则能保证监听事件触发的fn能拿到最新的变量a
由于a是在一秒后更新了一次,因此addEventListener函数也只更新了一次,fn里面的loading变量也只更新了一次, 后续loading的更新对fn参数无效, 所以triggerFn依赖变量a还不够,还需要依赖loading变量
这篇关于addEventListener与useeffect相撞的火花的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!