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() 用于优化重新渲染。该方法返回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; 方法,我们将获得完全相同的视觉结果,但没有不必要的重新渲染。

【讨论】:

以上是关于virtual-dom 和 shouldComponentUpdate的主要内容,如果未能解决你的问题,请参考以下文章

Cycle.js (virtual-dom) 是不是支持 React 的 refs 或 mithril 的 config 属性?

javascript基础修炼(10)——VirtualDOM和基本DFS

javascript基础修炼(10)——VirtualDOM和基本DFS

vue和react的区别

是啥因素促使虚拟 DOM 胜过浏览器原生 DOM? [关闭]

vDom和domDiff