【问题标题】:React: useCallback - useCallback with empty dependency array VS not using useCallback at all反应:useCallback - useCallback 与空依赖数组 VS 根本不使用 useCallback
【发布时间】:2020-06-10 13:06:51
【问题描述】:

我正在优化应用程序的性能,我想知道是否对不依赖任何变量的函数使用 useCallback 钩子。

考虑以下情况: 假设我们有一些功能:

const someFunc = () => {
  let someVar = "someVal";
  /**
   * here some extra calculations and statements regarding 'someVar'.
   * none of the statements depends on a variable outside this function scope.
   */
  return someVar;
};

这个函数不依赖任何变量,所以我们可以用 useCallback 把它包装成一个空数组:

const someFunc = useCallback(() => {
  let someVar = "someVal";
  return someVar;
}, []);

现在我的问题是 - 是否:

  • react 实际上声明了函数(包括内存分配和类似的东西):
const someFunc = () => {
  let someVar = "someVal";
  return someVar;
};
const someFuncCallback = React.useCallback(someFunc , [])
  • OR react 是否首先检查依赖项数组,如果没有任何依赖项更改为用于内存中先前分配的函数?

如果第一条语句为真,那么我们不应该在不依赖任何其他 var 的函数上使用 useCallback,因为无论如何该函数都会被重新声明。

但是如果第二个语句为真,那么我们应该在任何更“昂贵”的函数上使用 useCallback 钩子来声明一个单独的 useCallback 调用语句,但我不知道调用它来响应 useCallback 有多昂贵(来自内存和 CPU 使用情况)。


我发现this very nice blog 说第一句话是真的。但是如果你检查react docs about useCallback hook,你会看到它写着react useCallback 使用记忆调用,这意味着returning the cached result when the same inputs occur again,所以也许我没有得到一些东西,其中哪一个是正确的?

【问题讨论】:

  • 如果函数不依赖于任何变量,你应该把它移出组件。
  • 函数总是被分配的,但useCallback 将丢弃它并在依赖关系没有改变的情况下返回旧函数。当您将此函数进一步传递给记忆化组件时,这会影响性能。
  • at 依赖于其他 setState 钩子函数。
  • 打电话给你请参考一些文档来验证你的回答?

标签: javascript reactjs performance


【解决方案1】:

每次您的组件重新渲染时,都会创建一个新的函数实例,useCallback 只是将引用分配给另一个变量的附加功能

无论是否使用 useCallback,都会重新创建原始函数。

同样使用useCallback,react 实际上记住了作为参数传递给它的函数,如果依赖关系没有改变,则在下次重新渲染时返回函数的相同引用。

另请注意,如果您使用 useCallback 函数,如果您将该函数作为 prop 传递给子组件,它也会优化子组件的重新渲染。

因此,当您将函数传递给子组件或将其用作 useEffect 或使用 useCallback 调用的其他函数的依赖项时,使用 useCallback 挂钩是最佳选择

查看more details 的文档。

返回一个记忆回调。

传递一个内联回调和一个依赖数组。 useCallback 将 返回回调的记忆版本,仅在以下情况之一时更改 依赖关系已经改变。这在将回调传递给 优化的子组件依赖于引用相等来防止 不必要的渲染(例如shouldComponentUpdate)。

useCallback(fn, deps) 等价于useMemo(() => fn, deps)

【讨论】:

  • 谢谢你的回答,但这不是我问的。
  • 我更新了我的答案。也许这可以让您更深入地了解我想说的内容
  • 谢谢你,朋友。这正是我所问的。这正是 Alexey Lebedev 所说的。
猜你喜欢
  • 2020-03-07
  • 1970-01-01
  • 2021-09-29
  • 2021-06-27
  • 2020-07-29
  • 1970-01-01
  • 2023-03-25
  • 2020-04-26
  • 2020-09-15
相关资源
最近更新 更多