序
在客户端上,iOS和React的页面概念是不一样的。在React中,Component是非常重要的概念,是组成界面的主要元素。而在iOS中,ViewController和View是组成一个界面的主要元素。在iOS中ViewContoller相当于是很多View的集合体,处理多个view。而React中的Component是一个更加集中的概念,无论是一个页面, 还是一个页面中的子元素,都是Component。
Component
Component的生命周期
借用其他人的图,能够清楚的看出Component的相对于iOS的ViewController来说,还是要复杂一些。
Component的render
对于Component来说,当一个组件render调用的时候, 它的子组件也会去调用render,如下图:
component2是component1的子组件,component1是component0的子组件,当component0的state有变化,会触发component0的render,这个时候, 就算component1和component2的render都会被调用起来。
其实对于component1和component2来说,他们的render没有必要调用起来,(即使后面渲染的时候,他们不会被重新渲染,但是还是会做额度的比较)。
PureComponent
相对于Component来说,PureComponent是一个新能更高的版本。PureComponent的优势在于能够减少触发不必要的render。
PureComponent的生命周期
PureComponent的生命周期和Component的生命周期是一致的。
PureComponent的render
总体来说,PureComponent和Component的区别在于,PureComponent通过重写 shouldComponentUpdate
函数,减少了render的调用。
当组件更新时,如果组件的 props 和 state 都没发生改变, render 方法就不会触发,省去 Virtual DOM 的生成和比对过程,达到提升性能的目的。具体就是 React 自动帮我们做了一层浅比较:
if (this._compositeType === CompositeTypes.PureClass) {
shouldUpdate = !shallowEqual(prevProps, nextProps)
|| !shallowEqual(inst.state, nextState);
}
而 shallowEqual 又做了什么呢?会比较 Object.keys(state | props) 的长度是否一致,每一个 key 是否两者都有,并且是否是一个引用,也就是只比较了第一层的值,确实很浅,所以深层的嵌套数据是对比不出来的。
以上面的图举例:
假设component0、component1和component2都是PureComponent,如果component0的state发生了改变,component0的render被触发了,然而component1和component2是不会触发render的。
总结
以上图示例,当component0的state或者props发生变化时,component1的state和props没有变化时,
render函数的调用次数:
Component | PureComponent | |
---|---|---|
component0 | 多次调用 | 多次调用 |
component1 | 多次调用 | 不会调用 |
component2 | 多次调用 | 不会调用 |