React: useCallback - 具有空依赖数组的 useCallback VS 根本不使用 useCallback

Eli*_*ski 14 javascript performance reactjs

我正在优化应用程序的性能,我想知道是否在不依赖于任何变量的函数上使用 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;
};
Run Code Online (Sandbox Code Playgroud)

该函数不依赖于任何变量,因此我们可以使用 useCallback 和一个空数组来包装它:

const someFunc = useCallback(() => {
  let someVar = "someVal";
  return someVar;
}, []);
Run Code Online (Sandbox Code Playgroud)

现在我的问题是 - 是否:

  • React 实际上声明了该函数(带有内存分配和类似的东西):
const someFunc = () => {
  let someVar = "someVal";
  return someVar;
};
const someFuncCallback = React.useCallback(someFunc , [])
Run Code Online (Sandbox Code Playgroud)
  • 或者反应首先检查依赖项数组,如果没有任何依赖项更改用于内存中先前分配的函数?

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

但如果第二个语句为真,那么我们应该在任何比声明单个 useCallback 调用语句更“昂贵”的函数上使用 useCallback 钩子,但我不知道调用 useCallback 进行反应有多昂贵(从内存的角度来看)和 CPU 使用率)。


我发现这个非常好的博客说第一个陈述是正确的。但是如果你检查关于 useCallback 钩子的 React 文档,你会看到它写着 React useCallback 使用记忆调用,这意味着returning the cached result when the same inputs occur again,所以也许我没有得到一些东西,其中哪一个是正确的?

Shu*_*tri 13

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

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

此外,使用useCallbackReact 实际上会记住作为参数传递给它的函数,并且如果依赖项没有改变,则在下次重新渲染时返回该函数的相同引用。

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

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

检查文档以获取更多详细信息

返回一个记忆的回调。

传递内联回调和依赖项数组。useCallback 将返回回调的记忆版本,仅当依赖项之一发生更改时该版本才会更改。当将回调传递给依赖引用相等来防止不必要的渲染的优化子组件时,这非常有用(例如shouldComponentUpdate)。

useCallback(fn, deps)相当于useMemo(() => fn, deps).

  • 我更新了我的答案。也许这能让你对我想说的内容有更多的了解 (3认同)
  • 谢谢你,朋友。这正是我所问的。这正是阿列克谢·列别杰夫所说的。 (3认同)