在下面的Sandbox 项目中,我试图使用自定义挂钩来连接事件侦听器.

在useEventListener中.js文件,如果我传递savedHandler.直接将当前函数发送给事件侦听器(行号:21)在状态更新期间,我没有获得更新的状态值.只有当我使用savedHandler时.匿名函数中的当前函数(行号:19)我正在获取更新的状态值.

有人能帮我理解这是怎么回事吗?

https://codesandbox.io/s/gracious-cloud-kjw7dk?file=/src/useEventListener.js

谢谢

推荐答案

我只能这样解释:

对于上下文,当单击toggle flag按钮时,每次渲染后仅运行前useEffect(callback,[handler])次,第二个useEffect(callback,[eventName,element])只在初始渲染后运行一次.

  1. 现在,当您将savedHandler.current直接传递给事件侦听器(第21行)时,事件侦听器按原样附加useCallback返回的函数,因此在每个事件上,由于reasons:,正在调用相同的函数.事件仅注册一次,清理函数不运行,因为useEffect在初始渲染后仅运行一次(清理函数将在实例中运行,就在依赖关系更改引起的下一个副作用之前,以及组件卸载时).因此,您只需使用一个记忆回调来注册一次事件,该回调会在渲染过程中持续存在.第一个useEffectsavedHandler.current的更新不会更新传递给第二个useEffect中事件侦听器的回调,因为它不会重新运行,因此不会更新传递给事件侦听器的回调.
  2. 现在,当您在匿名函数中使用savedHandler.current函数时,这里的场景完全不同.当您将此类函数作为回调传递时,与第一个实例不同,在每个事件上都会调用一个新函数.尽管代码相同,但第一个事件和第二个事件的匿名回调并不相同.因此,在这里,您不必使用之前传递的同一个事件侦听器回调,因此您现在可以访问回调函数中由第一个useffect更新的最新记忆savedHandler.current值,尽管第二个效果不再运行.

就是这样.为了自己确认,try 在第二个useEffect上添加handler作为依赖项,并将savedHandler.current直接传递给事件侦听器.您将获得更新后的状态值,因为useEffect现在在handler的每次更新之后运行,并且事件侦听器获得要调用的最新回调.

Reactjs相关问答推荐

sourceBuffer. appendBuffer成功,但h5视频播放器卡住了

构建next.js项目时状态不变,但在dev服务器中

将对象添加到集合中的数组时的no_id字段

左边框不在图表中显示

Reaction路由DOM v6不包含上下文(Supabase)

在 React 中,为什么不将组件和钩子结合起来呢?

.populate() 方法在 mongodb 中不起作用

PWA:注册事件侦听器不会被触发

找不到名称setCometChat

修改React数据表扩展组件

React 组件列表中的第一个计时器正在获取值 NaN

如何在悬停时更改 MUI 卡内容

MUI TextField Select 菜单的最大高度

Redux Toolkit 配置,是否适用于全栈应用程序?

类型错误:类型typeof import(js-cookie)上不存在属性get

在 React 中使用复选框管理状态

使用 axios 响应路由 Dom 操作

React Router 6.4CreateBrowserRouter子元素不显示

用 scss 覆盖 MUI

单击当前子div时如何更改p标签的图像和样式?react