我们都知道memo包裹下的组件会在更新的时候浅比较props,从而达到减少渲染的目的。但是假如props没有变化,但是使用了context,那么react是如何保证组件能正常更新的呢。
在源码中我们看到,shallowEqual浅比较了props还有组件的类型,当满足的情况说明props没有变化。
则给didReceiveUpdate = false;,接下来会判断是否有更新的hook来决定是否要停止组件的更新渲染。
只有满足 !includesSomeLane(renderLanes, updateLanes)该条件才会退出组件的重新渲染。
当没有使用hook的情况下updateLanes为0,会直接退出组件的重新渲染
当有hook的情况下
可以看到
updateLanes为1,则需要重新渲染
那么updateLanes是什么时候变为1的呢,我们可以看到
lanes取的是当前fiber节点的lanes,那么他是何时变成1的呢
我们知道react每次更新都会自顶向下遍历整颗树,他会在context.provider节点时更新整棵树的lanes,保证其能正常更新。
当context发生变化,将会进入propagateContextChange方法,来更新整颗树的fiber
该方法会遍历Provider下的所有节点,判断fiber节点的dependency是否存在conext并且发生了变化,如果是clsssCopmnent给updateQueue添加一个强制更新的链表节点保证其可以重新渲染,如果是其他节点给fiber的lanes变成需要更新的lanes。
fiber中的dependency,是调用useContext时挂上的,useContext实际调用的时readContext