3

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

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

我看过很多关于这方面的视频,但我没有得到他们的确切行为方式。如果有人能清楚地解释以下疑问,那将是非常高兴的。

1) virtual DOM 是否每次都只渲染尚未渲染的组件,还是会有任何异常?

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

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

4

2 回答 2

2

1) virtual DOM 是否每次都只渲染尚未渲染的组件,还是会有任何异常?

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

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

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

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

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

shouldComponentUpdate(nextProps, nextState) {
  if(this.props.abc !== nextProps.abc) {
    // anything you want to do and return true or false accordingly
  }
}
于 2017-10-22T18:17:27.443 回答
2

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

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

答案是不。

原因是当这个协调过程发现树上的一个组件有差异时,出于差异算法的性能原因,它将重新渲染整个子树

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

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; }向它添加一个方法,我们将获得完全相同的视觉结果,但没有不必要的重新渲染。

于 2018-03-22T08:25:42.620 回答