React 源码探源 3 Update 的整体流程
2021-06-22 本文已影响0人
吴摩西
综述
书接上一章节: React 源码探源 2 Mount 复杂的例子.
参考上文提到的 fibre tree,如下
跟踪 update 调用栈,发现如下:
Update 调用栈
debug 到源码中,可以绘制主要的调用流程如下:
Update 主要流程
主要的流程可以分为三个阶段,事件响应,Render, Commit。
事件响应
值得注意的是,虽然事件是从 button
中触发,最终也是触发了 button
的 onClick
回调函数。整体的事件处理却不是从 button
的 DOM 节点触发。却是
- 通过事件的冒泡机制上抛到
div#container
,再从div#container
整体处理 - 在
extractEvent$5
根据event.target
找到事件的冒泡路径上的所有响应函数。响应函数是从 DOM 节点对应的_reactProps
属性中读出的。 - 本例中,
onClick
含有setState
的调用,setState
中会将fiber Dev()
的lanes
设置为 1。 - 事件的回调会通过
scheduleLegacySyncCallback
将performSyncWorkOnRoot
push 到syncQueue
中,并会更新根结点 lanes ,阻止再次将回调推进syncQueue
- 最终会通过
flushSyncCallbacks
调用syncQueue
中的回调。
Render 阶段
- 如果 fiber 的 props 有所变动,会有标记
didReceiveUpdate = true
。 - 如果 fiber 的 lances 有所变动或者有 context,才会执行函数组件或者类组件的
render
函数。如果有state
变动,也会标记didReceiveUpdate = true
。 - 如果 fiber 的 lances 没有变动,也没有 props 变动,会执行
bailoutOnAlreadyFinishedWork
跳过对应的
beginWork
阶段。不会执行组件对应的 render 函数。 - 当执行对应的
HostText
completeWork
阶段时,会检查对应的props
变动,标记对应的 flag为4(Update)
,当有类似的变动时,会标记其所有的父节点的subtreeFlag
也有4(Update)
Commit 阶段
commitMutationEffects
会检查 fiber 的 flag
和 subtreeFlag
执行对应的更新操作。本阶段的更新过程会在后续的序列中继续探究。