0

从组件返回的这两种形式:

  <button onClick={(e) => this.handleClick(e)}>

或者

  <button onClick={this.handleClick.bind(this)}>

每次创建一个新函数。据说这是一个问题。但究竟是什么问题?

文档说:

这种语法的问题是每次 LoggingButton 呈现时都会创建不同的回调。在大多数情况下,这很好。但是,如果此回调作为道具传递给较低的组件,则这些组件可能会进行额外的重新渲染。

但这不是错误的概念吗?

1)首先,这本身就是一个问题,即使它没有传递给较低的组件。因为当它被渲染到一个虚拟 DOM 树时,它与之前的虚拟 DOM 树进行比较,并且看到它是一个不同的点击处理程序,它需要更新实际的 DOM——要么通过更改onclick属性,要么通过removeEventListener()addEventListener()更改处理程序。通常我们不想更新实际的 DOM,因为它比虚拟 DOM 昂贵得多。

2)其次,无论它被传递给较低的组件,较低的组件无论如何都会重新渲染。除非较低的组件是 PureComponent 或由 React.memo() 优化。但如果它们只是组件,则无论如何都会重新渲染较低的组件。所以这传达了一个错误的概念。它可能会导致较低组件中的实际 DOM 更新,但这已经在 (1) 中进行了介绍,并且无论它是否向下传递到较低组件都是如此。

3) 一种可能性是更改事件侦听器不像其他实际 DOM 操作那样昂贵,因此值得关注的是,如果单击处理程序被传递给较低的组件并且组件使用 PureComponent 或 React.memo 来不重新渲染时道具没有改变,传入新的处理程序将导致较低的组件重新渲染。但只有在较低的组件不是常规组件时才会出现这种情况。

所以实际的问题是需要对实际的 DOM 进行更新。

并且上面的“重新渲染”这个词并不意味着对实际 DOM 的更新。“重新渲染”意味着创建一个虚拟 DOM 树,或者通过render()类组件的 ,或者通过返回 React 元素的函数组件,就像render(). (只是为了确保我们在谈论同一件事)。

4

0 回答 0