virtual-dom和shouldComponentUpdate

时间:2017-10-22 15:00:06

标签: reactjs virtual-dom

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

如果虚拟DOM仅呈现尚未呈现的DOM,为什么我应该使用shouldComponentUpdate()方法。

我已经看了很多关于这个的视频,但我没有得到他们表现的确切方式。如果有人能够清楚地解释以下疑惑,那将是一件非常愉快的事。

1)虚拟DOM是否每次只呈现尚未呈现的组件或是否存在异常?

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

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

2 个答案:

答案 0 :(得分:2)

1)虚拟DOM是否每次只呈现尚未呈现的组件或是否会有例外?

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

2)如果虚拟DOM每次都只渲染尚未渲染的组件,那么当父道具发生变化时,为什么子组件会重新渲染?

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

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

shouldComponentUpdate()用于优化重新渲染。该方法返回truefalse。由您决定如何渲染和重新渲染组件。它基本上用于性能增强。有些情况下,即使状态更改,您也不希望组件重新渲染,因此您可以使用此方法。例如:

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

答案 1 :(得分:2)

我认为之前的回复并不是针对被问到的问题。 我相信,实质上,问的是:

Virtual DOM对帐流程是否会使shouldComponentUpdate()方法变得多余?

答案是否定的。

原因是当reconciliation process找到树上组件的差异时,出于性能原因,它会重新渲染整个子树

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

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