【问题标题】:virtual-dom and shouldComponentUpdatevirtual-dom 和 shouldComponentUpdate
【发布时间】:2018-04-03 04:27:21
【问题描述】:

如果我是对的,ReactJS 中的 Virtual DOM 会将之前的 DOM 与当前 DOM 进行比较,即在状态树更改后形成。那为什么当父道具发生变化时子组件会重新渲染。

如果虚拟 DOM 只渲染尚未渲染的 DOM,我为什么要使用shouldComponentUpdate() 方法。

我看过很多关于这方面的视频,但我并没有完全了解它们的行为方式。如果有人能清楚地解释以下疑惑,那将是非常高兴的。

1) virtual DOM 是否每次都只渲染没有渲染的组件,还是会出现异常?

2)如果virtual DOM每次只渲染没有渲染的组件,为什么子组件在父props发生变化时会重新渲染?

3)什么时候应该使用shouldComponentUpdate()

【问题讨论】:

    标签: reactjs virtual-dom


    【解决方案1】:

    1) virtual DOM 是否每次都只渲染未渲染的组件,还是会出现异常?

    虚拟 DOM 是 HTML DOM 的抽象。由于 DOM 本身已经是一个抽象,虚拟 DOM 实际上是一个抽象的抽象。虚拟 DOM 所做的不是渲染整个页面,而是仅渲染发生更改的组件。可能所有组件都已经存在,但如果一个组件发生更改,它只会重新呈现该组件。

    2)如果virtual DOM每次只渲染未渲染的组件,为什么子组件在父props发生变化时会重新渲染?

    当父 props 发生变化时子组件重新渲染是因为 props 被传递给子组件并且它们根据这些 props 运行。并且如上所述,只要有变化,组件就会重新渲染。

    3) 我应该什么时候使用 shouldComponentUpdate()?

    shouldComponentUpdate() 用于优化重新渲染。该方法返回truefalse。您希望组件如何渲染和重新渲染取决于您。它主要用于性能增强。在某些情况下,即使状态更改,您也不希望组件重新渲染,因此您使用此方法。例如:

    shouldComponentUpdate(nextProps, nextState) {
      if(this.props.abc !== nextProps.abc) {
        // anything you want to do and return true or false accordingly
      }
    }
    

    【讨论】:

      【解决方案2】:

      我认为之前的回复没有解决所提出的问题。 我相信比本质上,要问的是:

      Virtual DOM 协调过程不会使shouldComponentUpdate() 方法变得多余吗?

      答案是否定的。

      原因是当这个reconciliation process发现树上的一个组件有差异时,出于diffing算法的性能原因,它会重新渲染整个子树

      通过以下简单示例可以清楚地理解这一点:

      class NothingChanges extends React.Component {
          render() {
              return <h3>Nothing changed here...</h3>;
          }
      }
      
      class Counter extends React.Component {
          state = { value: 0 };
      
          increment = () => {
              this.setState(
                  prevState => ({ value: prevState.value + 1 })
              );
          };
      
          render() {
              return (
                  <div>
                      <h2 onClick={this.increment}>{this.state.value}</h2>
                      <NothingChanges />
                  </div>
              );
          }
      }
      

      虽然NothingChanges 组件没有任何变化,但每次父组件更改其状态时都会调用其渲染函数。

      如果我们向它添加shouldComponentUpdate() { return false; } 方法,我们将获得完全相同的视觉结果,但没有不必要的重新渲染。

      【讨论】:

        猜你喜欢
        • 2019-10-20
        • 2018-10-27
        • 2018-12-28
        • 2018-04-01
        • 2017-02-05
        • 2021-05-04
        • 2018-03-03
        • 2016-06-30
        • 2020-03-26
        相关资源
        最近更新 更多