React中useEventListener Hook获取更新状态的机制疑问
自定义Hook事件监听的状态捕获问题解析
核心原理:闭包特性导致,和this无关
直接绑定savedHandler.current时:
- 组件状态更新会触发重渲染,
useEventListener会重新执行,savedHandler.current会被更新为包含最新状态的新handler函数。 - 但
addEventListener绑定的是第一次传入的旧handler引用,这个旧函数是在初始渲染时创建的,它的闭包捕获的是当时的旧状态,所以状态更新后,触发事件时还是用的旧函数,拿不到新状态。
用匿名函数包裹时:
- 事件监听器绑定的是这个匿名函数,它本身不捕获任何状态。
- 每次事件触发时,才会去读取
savedHandler.current的最新值(因为useRef的current是跨渲染周期可变的,每次重渲染都会把最新的handler存进去),所以能拿到更新后的状态。
关键细节
useRef的作用就是保存一个跨渲染周期的可变引用,它不会像状态变量那样触发重渲染,因此可以安全地存储每次更新后的handler函数。- 这种写法通过间接引用避开了闭包的状态捕获限制,确保事件触发时总能拿到最新的函数版本。
内容的提问来源于stack exchange,提问作者tadain
相关产品推荐
相关产品推荐

