反应:useCallback-useCallback与空的依赖数组VS根本不使用useCallback

时间:2020-06-10 13:06:51

标签: javascript reactjs performance

我正在优化应用程序的性能,我想知道是否在不依赖任何变量的函数上使用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是否先检查依赖项数组,以及是否没有更改依赖项以用于内存中先前分配的功能?

如果第一条语句为true,则我们不应在不依赖于任何其他var的函数上使用useCallback,因为无论如何该函数将被再次声明。

但是如果第二条语句为true,那么我们应该在任何更“昂贵”的函数上使用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),所以也许我听不到一些信息,其中哪一项是正确的?

2 个答案:

答案 0 :(得分:3)

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

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

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

还请注意,如果您使用useCallback函数,则在将子函数作为道具传递给子组件时,它也会优化子组件的重新渲染。

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

检查文档中的more details

返回一个已记忆的回调。

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

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

答案 1 :(得分:0)

好久没提这个问题了,今天终于可以回答了。

第一件事:声明一个函数和执行一个函数之间有很大的区别。当你用 useCallback 包装一个函数时,它实际上会记住(记住上次执行结果),下次你调用这个函数时,如果依赖数组中的任何值都没有改变,它将返回最后一个结果。

这意味着,例如,如果在仅在渲染时调用的函数上使用 useCallback 是无用的,因为无论如何它都会执行一次。无论如何,每次渲染都会发生声明。