如果我是对的,ReactJS中的Virtual DOM
会将之前的DOM
与当前的DOM进行比较,即在状态树发生更改后形成的。那么当父道具发生变化时,为什么子组件会重新出现。
如果虚拟DOM仅呈现尚未呈现的DOM,为什么我应该使用shouldComponentUpdate()
方法。
我已经看了很多关于这个的视频,但我没有得到他们表现的确切方式。如果有人能够清楚地解释以下疑惑,那将是一件非常愉快的事。
1)虚拟DOM是否每次只呈现尚未呈现的组件或是否存在异常?
2)如果虚拟DOM每次只渲染尚未渲染的组件,为什么子组件在父道具发生变化时会重新渲染?
3)我什么时候应该使用shouldComponentUpdate()
?
答案 0 :(得分:2)
1)虚拟DOM是否每次只呈现尚未呈现的组件或是否会有例外?
Virtual DOM是HTML DOM的抽象。由于DOM本身已经是抽象,因此虚拟DOM实际上是抽象的抽象。虚拟DOM所做的不是呈现整个页面,而是仅呈现具有更改的组件。可能存在所有组件,但如果在一个组件中发生了更改,则只会重新呈现该组件。
2)如果虚拟DOM每次都只渲染尚未渲染的组件,那么当父道具发生变化时,为什么子组件会重新渲染?
当父道具发生变化时,子组件会重新渲染,因为道具会传递给子组件,并且它们会根据这些道具行为。如上所述,只要有变化,组件就会重新渲染。
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
}
}
答案 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; }
方法,我们将获得完全相同的视觉效果,但没有不必要的重新渲染。