如何在不每次创建新回调的情况下将回调作为道具传递给 React 中的低级组件?

How to pass callback as a prop to lower components in React without creating a new callback each time?

我从 angular 过来,习惯了反应。我正在阅读有关事件处理的文档并偶然发现了这一点:

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // This syntax ensures `this` is bound within handleClick
    return (
      <button onClick={() => this.handleClick()}>
        Click me
      </button>
    );
  }
}

文档然后说:

此语法的问题是每次呈现 LoggingButton 时都会创建不同的回调。在大多数情况下,这很好。但是,如果此回调作为 prop 传递给较低的组件,则这些组件可能会进行额外的重新渲染。我们通常建议在构造函数中绑定或使用 class 字段语法,以避免此类性能问题。"

我无法访问构造函数,因为我正在使用挂钩。我该怎么办?

我准备了一个快速demo。结构为 App > [CompA > Comp B]。组件 B 中有一个递增计数的按钮,计数的状态保存在 App 中。通过道具,回调从 App 通过 Comp A 委托给 comp B。每当我单击 Comp B 中的计数按钮时,它都会重新呈现整个 Comp A。这可以通过随机数生成来验证。这个组件没问题,但在大型项目中这不会成为问题吗?

现在假设我有一个测验应用程序并且我在主应用程序中记录分数。如果有人在问题组件中选择了正确答案,我想在主应用程序中保留一个计数。这样做会重新渲染任何中间组件。我应该遵循什么模式?

使用 useCallback 钩子。只要其依赖关系保持不变,它就会 return 具有相同的功能。

const callback = useCallback(()=> { /* do something */ }, [/* dependencies */])

依赖项与 useEffect 挂钩的工作方式相同。

编辑

根据您的演示,<CompA onCount={() => setCount(count + 1)} /> 非常好,Dan Abramov 也这么说。

父级 re-renders 将呈现其子级,因此如果计数状态在父级中,则子级将为 re-rendered。那很好。 React 的构建就是为了非常快速地做到这一点。