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 如何“冻结”闭包? 的相关文章

随机推荐