1

TL;博士

有的博客说不需要useCallback每次给子组件传递回调时都使用钩子,有时每次都创建一个新函数会更好。因为useCallback有时成本高于实际性能问题。虽然 React 警告说它可能会导致性能问题,但我们需要尽量避免它。
谁是对的,在这两种对立的主张之间取得平衡的方法是什么?

完整的问题

我最近一直在阅读很多关于 React hooks 的博客和教程,特别是关于useCallbackuseMemo.

在 React 16(及其所有钩子)之前,当我使用类组件时,我一直使用“构造函数绑定”进行回调,因为箭头函数或“渲染中的绑定”如下所示:

render() {
  return <button onClick={this.handleClick.bind(this)}>Click Me</button>;
}

render() {
  return <button onClick={() => this.handleClick()}>Click Me</button>;
}

被认为是“不良做法”。来自React 文档

在渲染中使用 Function.prototype.bind 会在每次渲染组件时创建一个新函数,这可能会影响性能(见下文)。

在渲染中使用箭头函数会在每次渲染组件时创建一个新函数,这可能会破坏基于严格标识比较的优化。

所以,我的经验法则是不要将新函数传递给 props。

在 React 16 中,useCallback钩子试图帮助我们做那件事。但是我看到很多类似的博客声称不需要每次都使用钩子,因为有时成本高于实际问题,并且使用箭头函数在每次渲染时创建一个新函数很好。useCallbackuseCallback

两种相反的说法都让我认为最好的选择应该是这样的(如果依赖项数组为空):

function handleCallback() { ... } // Or arrow function...

function Foo(props) {
   return <button onClick={handleCallback}>Click Me</button>
}

因为这种方式不使用“昂贵” useCallback,并且不会每次都生成新功能。但是,实际上,当您有多个回调时,这段代码看起来并不那么好。

那么,这两种对立的主张之间的正确平衡是什么?如果每次创建一个新函数有时比使用更好useCallback,为什么 React 在他们的文档中有一个警告?

(关于“双花括号”经验法则和useMemo/useRef钩子的相同问题)

4

0 回答 0