Last updated
Last updated
shouldComponentUpdate 是 PureRender 的关键之所在,这个生命周期钩子函数决定了需不需要执行 render 方法。一个组件的状态更新到真实 dom 的更新大致流程如下:
以 为例,补充说明如下:
SCU
表明了shouldComponentUpdate
的返回内容,绿色代表 true,会重新执行 render 方法;红色代表 false,不会执行 render 方法。
vDOMEq
表明了执行 v-diff 后待渲染的 v-dom 与原始 v-dom 是否相等,绿色代表相等,红色代表不等,需要更新 dom。
圆圈的颜色表明这个组件是否需要更新 dom,红色和 vDOMEq
的值的颜色一致。
由于 C2 的shouldComponentUpdate
返回了false
,React 不会调用 C2 的 render 方法,也就不会生成 v-dom,甚至不会在 C4 和 C5 上调用shouldComponentUpdate
。
对 C1 和 C3 来说,shouldComponentUpdate
返回了true
,因此 React 会深入到分支中并检查它们。C6 的shouldComponentUpdate
返回了true
,然后进行 v-diff,由于 vDOMEq
返回 false,React 会更新这个真实的 DOM 节点。
最后一个有趣的情况是 C8,SCU
为 true 会调用 render 方法进行 v-diff,但是由于vDOMEq
返回 true,因此它并没有更新这个真实的 DOM 节点。
分析完以上所有过程,我们会发现 React 只需更新 C6 的真实 DOM 节点,因为它是不可避免的。对C8来说,它通过 v-diff 避免了更新真实 DOM,对 C2 的子树和 C7,它们甚至都没有执行比较,因为我们设置了shouldComponentUpdate
为false
,render
没有被调用。
注意:虽然 C1 和 C3 节点被标记为红色,但实际更新真实 DOM 的时候只会更新 C6 节点。
PureRender 的本质就是把 shouldComponentUpdate 函数用浅比较(shallowCompare)进行重写。
以下是 React 中 shallowCompare.js
的核心源码: