React Hooks useCallback 如何“冻结”闭包?

2023-11-22

我想知道 React 如何在使用时“冻结”闭包useCallback钩子(以及其他钩子),然后仅在将钩子内使用的变量传递到inputs范围。

我知道“冻结”可能不是很清楚,所以我创建了一个 REPL.it 来显示我的意思:https://repl.it/repls/RudeMintcreamShoutcast。打开代码后,打开网络浏览器控制台并开始单击count button.

对于同一个变量,如果它们位于相同的闭包下并引用相同的事物,那么为什么外部的值与内部的值不同?我不熟悉 React 代码库,所以我想我在这里错过了底层的实现细节,但我试图思考它如何工作几分钟,但无法很好地理解 React 是如何工作的实现这一点。


第一次渲染组件时,useCallbackhook 会将传递的函数作为其参数并将其存储在幕后。当您调用回调时,它会调用您的函数。到目前为止,一切都很好。

第二次渲染该组件时,useCallbackhook 将检查您传入的依赖项。如果它们没有更改,你传入的函数被完全忽略!当您调用回调时,它将调用您在第一次渲染时传入的函数,该函数仍然引用该时间点的相同值。这与您作为依赖项传入的值无关 - 这只是普通的 JavaScript 闭包!

当依赖关系发生变化时,useCallbackhook 将获取您传入的函数并替换它存储的函数。当你调用回调时,它会调用new函数的版本。

换句话说,没有“冻结”/有条件更新的变量 - 它只是存储一个函数然后重新使用它,没有比这更奇特的了:)

EDIT:下面的示例演示了纯 JavaScript 中发生的情况:

// React has some component-local storage that it tracks behind the scenes.
// useState and useCallback both hook into this.
//
// Imagine there's a 'storage' variable for every instance of your
// component.
const storage = {};

function useState(init) {
  if (storage.data === undefined) {
    storage.data = init;
  }
  
  return [storage.data, (value) => storage.data = value];
}

function useCallback(fn) {
  // The real version would check dependencies here, but since our callback
  // should only update on the first render, this will suffice.
  if (storage.callback === undefined) {
    storage.callback = fn;
  }

  return storage.callback;
}

function MyComponent() {
  const [data, setData] = useState(0);
  const callback = useCallback(() => data);

  // Rather than outputting DOM, we'll just log.
  console.log("data:", data);
  console.log("callback:", callback());

  return {
    increase: () => setData(data + 1)
  }
}

let instance = MyComponent(); // Let's 'render' our component...

instance.increase(); // This would trigger a re-render, so we call our component again...
instance = MyComponent();

instance.increase(); // and again...
instance = MyComponent();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React Hooks useCallback 如何“冻结”闭包? 的相关文章

  • Hooks setState 总是落后一步

    我使用了 useState 钩子 应该在每次下拉按钮的值发生变化时触发设置状态方法 在钩子中 但设置状态总是落后一步 我已经看到了使用基于类的组件的传统 setState 方法的解决方案 但是如何使用钩子解决此问题useState
  • 如何使用react-router将this.state和this.props传递给路由

    我不知道如何从我的父 ReactJS 组件访问方法post路线和组件 使用react router 这是在
  • @Mui 和模块化 scss 间歇性竞争的问题。如何使用 scss 模块一致地覆盖 @mui 默认样式?

    因此 我正在使用 mui material 组件的现有 React 应用程序进行构建 我有 scss 模块连接到我的 javascript 组件 并像这样使用材质组件导入它们 STYLE IMPORT import styles from
  • 在nextjs中获取URL路径名

    我有一个登录页面和布局组件 布局组件有标题 我不想在登录中显示标题 为此 我想获取 url 路径名 基于路径名显示标题 import as constlocalStorage from helpers localstorage import
  • 如何将 google 字体添加到 gatsby 网站

    Gatsby 入门 当我使用 google 字体将链接标记添加到 public index html 时 它可以在开发模式下工作 当我构建网站时 index html 会被重置 所以我想还有另一种添加字体的正确方法吗 您还可以使用反应头盔
  • axios在自调用函数内部只调用一次(Internet Explorer)

    我有一个函数每 2 5 秒调用自己一次来检查后台运行的任务 它调用 axiosget如果响应错误 则返回一个 url 如果响应成功 我将停止该函数 这在 Chrome 和 Mozilla 上完美运行 但由于某种原因 它在 IE 版本 11
  • 在我的反应应用程序中使用笑话,描述未定义

    我是开玩笑的新手 试图在下面的代码中找出一些基本的东西 import as actions from IncrementalSearchActions describe Incremental Search Actions gt it Sh
  • RouteComponentProps 与 useHistory

    使用React功能组件和Typescript 使用useHistory钩子与RouteComponentProps react router v5 1 之间有什么区别吗 使用 RouteComponentProps 的示例 import R
  • 使用 AntD 样式响应 Hook 表单

    我试图弄清楚如何将react hook form与antd前端一起使用 我已经制作了这个表单 它似乎正在工作 它是多部分表单向导的第 1 部分 只是不显示错误消息 谁能看到我在合并这两个表单系统时做错了什么 我没有收到任何错误 但我认为我已
  • Material UI 切换按钮 - 选择时无法更改背景颜色

    我正在尝试使用类似于单选按钮的 Material UI 切换按钮 为用户提供针对给定问题的 2 个选择 它的功能基本符合预期 但是当尝试调整选择每个切换按钮时的样式时 我无法更改切换按钮的背景颜色 我在 ToggleButton 组件上使用
  • Phonegap应用程序与reactjs [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 有人用reactjs 通过facebook 编写了phonegap应用程序吗 任何指向参考实现的指针将不胜感激 此外 您建议将什么数据
  • ReactJS 模式无法使用 Materialise css 打开

    我是 ReactJS 的新手 正在学习使用 Materialise css 创建模型 https materializecss com https materializecss com import React Component from
  • ReactJS 服务器端渲染与客户端渲染

    我刚刚开始研究ReactJS 发现它提供了两种渲染页面的方式 服务器端和客户端 但是 我不明白如何一起使用它 构建应用程序是两种不同的方法 还是可以一起使用 如果我们可以一起使用它 该怎么做 我们需要在服务器端和客户端复制相同的元素吗 或者
  • 如何在React Router 4中实现动态路由?

    我有一个这样的文章列表 div this props articles map article gt return div
  • React Router LINK不传递参数

    我有一个 React 有声读物搜索应用程序 它按作者姓氏从 Librivox 获取数据并显示书籍列表 列表中的每个项目都有一个链接 该链接依次转到显示的单独的完整图书数据组件 该特定书籍 或用户从列表中选择的任何书籍 的所有数据 在我的一生
  • useRef 和普通变量的区别

    我想知道这两个代码之间的区别 1 import React from react import ReactDOM from react dom function App const myref React useRef 0 2 import
  • 查询字符串的 URL 与反应路由器路由不匹配

    鉴于此 React 路由器配置
  • getFieldValue 或 Formik 中的类似内容

    有没有办法获取 formik 中单击处理程序内字段的值 您可以使用setFieldValue在那里 所以我假设 但在任何地方都找不到 Formik 应该有类似的东西来检索值
  • 在react-pdf中显示pdf时出错

    我是新来反应的 我正在尝试在浏览器上显示 pdf 文件 我收到错误如下加载 PDF 失败 我正在尝试运行中给出的示例程序https www npmjs com package react pdf https www npmjs com pa
  • 如何检查令牌过期和注销用户?

    当用户单击注销按钮时 他 她可以自己注销 但是如果令牌过期 他 她就无法注销 因为在我的应用程序中 令牌在服务器端和前端都使用 当用户单击注销按钮时 如果令牌有效 则服务器和浏览器中的令牌都会被清除 当用户未注销并且他 她的令牌过期但未在浏

随机推荐