我只能这样解释:
对于上下文,当单击toggle flag按钮时,每次渲染后仅运行前useEffect(callback,[handler])
次,第二个useEffect(callback,[eventName,element])
只在初始渲染后运行一次.
- 现在,当您将savedHandler.current直接传递给事件侦听器(第21行)时,事件侦听器按原样附加
useCallback
返回的函数,因此在每个事件上,由于reasons:,正在调用相同的函数.事件仅注册一次,清理函数不运行,因为useEffect
在初始渲染后仅运行一次(清理函数将在实例中运行,就在依赖关系更改引起的下一个副作用之前,以及组件卸载时).因此,您只需使用一个记忆回调来注册一次事件,该回调会在渲染过程中持续存在.第一个useEffect
中savedHandler.current的更新不会更新传递给第二个useEffect
中事件侦听器的回调,因为它不会重新运行,因此不会更新传递给事件侦听器的回调.
- 现在,当您在匿名函数中使用savedHandler.current函数时,这里的场景完全不同.当您将此类函数作为回调传递时,与第一个实例不同,在每个事件上都会调用一个新函数.尽管代码相同,但第一个事件和第二个事件的匿名回调并不相同.因此,在这里,您不必使用之前传递的同一个事件侦听器回调,因此您现在可以访问回调函数中由第一个useffect更新的最新记忆savedHandler.current值,尽管第二个效果不再运行.
就是这样.为了自己确认,try 在第二个useEffect
上添加handler作为依赖项,并将savedHandler.current直接传递给事件侦听器.您将获得更新后的状态值,因为useEffect
现在在handler的每次更新之后运行,并且事件侦听器获得要调用的最新回调.