virtual-dom 和 shouldComponentUpdate
Posted
技术标签:
【中文标题】virtual-dom 和 shouldComponentUpdate【英文标题】:virtual-dom and shouldComponentUpdate 【发布时间】:2018-04-03 04:27:21 【问题描述】:如果我是对的,ReactJS 中的 Virtual DOM
会将之前的 DOM
与当前 DOM 进行比较,即在状态树更改后形成。那为什么当父道具发生变化时子组件会重新渲染。
如果虚拟 DOM 只渲染尚未渲染的 DOM,我为什么要使用shouldComponentUpdate()
方法。
我看过很多关于这方面的视频,但我并没有完全了解它们的行为方式。如果有人能清楚地解释以下疑惑,那将是非常高兴的。
1) virtual DOM 是否每次都只渲染没有渲染的组件,还是会出现异常?
2)如果virtual DOM每次只渲染没有渲染的组件,为什么子组件在父props发生变化时会重新渲染?
3)什么时候应该使用shouldComponentUpdate()
?
【问题讨论】:
【参考方案1】:1) virtual DOM 是否每次都只渲染未渲染的组件,还是会出现异常?
虚拟 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
【讨论】:
【参考方案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;
方法,我们将获得完全相同的视觉结果,但没有不必要的重新渲染。
【讨论】:
以上是关于virtual-dom 和 shouldComponentUpdate的主要内容,如果未能解决你的问题,请参考以下文章
Cycle.js (virtual-dom) 是不是支持 React 的 refs 或 mithril 的 config 属性?
javascript基础修炼(10)——VirtualDOM和基本DFS
javascript基础修炼(10)——VirtualDOM和基本DFS