React提供了一种基于浅比较模式来确定是否应该重新渲染组件的类React.PureComponent,通常只需要继承React.PureComponent就可以定义一个纯组件。React.PureComponent与React.Component很相似,两者的区别在于React.Component并未实现shouldComponentUpdate(),而React.PureComponent中以浅层对比prop和state的方式来实现了该函数。如果赋予React组件相同的props和state,render()函数会渲染相同的内容,那么在某些情况下使用React.PureComponent可提高性能。
首先我们来回顾下React组件执行重渲染re-render更新的时机,一般当一个组件的props属性或者state状态发生改变的时候,也就是父组件传递进来的props发生变化或者使用this.setState函数时,组件会进行重新渲染re-render。而在接受到新的props或者state到组件更新之间会执行其生命周期中的一个函数shouldComponentUpdate,当该函数返回true时才会进行重渲染,如果返回false则不会进行重渲染,在这里shouldComponentUpdate默认返回true,因此当组件遇到性能瓶颈的时候可以在shouldComponentUpdate中进行逻辑判断,来自定义组件是否需要重渲染。
我们可以稍微查看一下源码的实现,可以看到PureComponent是通过寄生组合继承的方式继承了Component,commit id为 0cf22a5。
同时在checkShouldComponentUpdate函数中有一段这样的逻辑,在函数名上就能看出是对传入的参数进行了一次浅比较,因此实际上PureReactComponent组件和ReactComponent组件的区别就是React.PureComponent中以浅层对比prop和state的方式来实现了shouldComponentUpdate()函数。
需要注意的是,React.PureComponent中的shouldComponentUpdate()仅作对象的浅层比较。如果对象中包含复杂的数据结构,则有可能因为无法检查深层的差别,产生错误的比对结果。仅在你的props和state较为简单时才使用React.PureComponent,或者每次更新都使用新的对象,或者在深层数据结构发生变化时调用forceUpdate()来确保组件被正确地更新,你也可以考虑使用immutable对象加速嵌套数据的比较。此外React.PureComponent中的shouldComponentUpdate()将跳过所有子组件树的prop更新,因此需要确保所有子组件也都是纯的组件。
shouldComponentUpdate生命周期做了优化会自动shadow diff组件的state和props,结合immutable数据就可以很好地去做更新判断。shouldComponentUpdate中的shadow diff同样消耗性能。props与state。