Open UNDERCOVERj opened 6 years ago
在 reconciliation 生成一系列 child fibers 后,会进入 completeUnitOfWork 阶段。如果 workInProgress 对应的 fiber 是需要更新的 HostComponent (请注意,不是说的第一次渲染页面,判断逻辑如下)
reconciliation
child fibers
completeUnitOfWork
workInProgress
fiber
HostComponent
workInProgress.alternate !== null && workInProgress.stateNode != null
那么需要对 props 进行 diff 区分,如果有不一样的键值对,则加入到 updatePayload 数组中,并挂载到 workInProgress.updateQueue
props
diff
updatePayload
workInProgress.updateQueue
diffProperties$1
新旧 props 分别为:lastProps , nextProps ,如果 lastProps[propKey] === nextProps[propKey] 则跳过
lastProps
nextProps
lastProps[propKey] === nextProps[propKey]
对比 lastProps.style 和 nextProps.style
lastProps.style
nextProps.style
(updatePayload = updatePayload || []).push('style', {top: '20px', left: ''})
(updatePayload = updatePayload || []).push('style', nextProps.style)
当 children 为文本(string 、number )且有变化时
children
string
number
(updatePayload = updatePayload || []).push('children', '' + nextProps.children)
如果nextProps.propKey有值,在 document 上绑定 eventName 函数,确保能触发 dispatchEvent 回调函数。如果新旧props的props[eventName]不一样,则:
document
eventName
dispatchEvent
updatePayload = [];
当 diff 完有差异,updatePayload 就为数组,否则,updatePayload 为 null。
null
待 updatePayload 返回后,在 updateHostComponent 中,将 updatePayload 挂载在 workInProgress.updateQueue 上,并且 updatePayload 不为 null ,则将 workInProgress 标志为更新
updateHostComponent
workInProgress.updateQueue = updatePayload; if (updatePayload) { // 这会把Placement变为UpdateAndPlacement workInProgress.effectTag |= Update; }
在最后的 commitWork 阶段,才根据 effectTag 来执行视图的更新
commitWork
effectTag
dom
目前已经将作者写的基本消化完了,很感谢你的总结,按照你的思路进行学习很好!辛苦了!
@yeziTesting 加油
在
reconciliation
生成一系列child fibers
后,会进入completeUnitOfWork
阶段。如果workInProgress
对应的fiber
是需要更新的HostComponent
(请注意,不是说的第一次渲染页面,判断逻辑如下)那么需要对
props
进行diff
区分,如果有不一样的键值对,则加入到updatePayload
数组中,并挂载到workInProgress.updateQueue
具体diff函数:
diffProperties$1
新旧
props
分别为:lastProps
,nextProps
,如果lastProps[propKey] === nextProps[propKey]
则跳过对比
lastProps.style
和nextProps.style
(updatePayload = updatePayload || []).push('style', {top: '20px', left: ''})
lastProps.style
没有定义(updatePayload = updatePayload || []).push('style', nextProps.style)
当
children
为文本(string
、number
)且有变化时如果nextProps.propKey有值,在
document
上绑定eventName
函数,确保能触发dispatchEvent
回调函数。如果新旧props的props[eventName]不一样,则:diff完后
当
diff
完有差异,updatePayload
就为数组,否则,updatePayload
为null
。待
updatePayload
返回后,在updateHostComponent
中,将updatePayload
挂载在workInProgress.updateQueue
上,并且updatePayload
不为null
,则将workInProgress
标志为更新在最后的
commitWork
阶段,才根据effectTag
来执行视图的更新diff的作用
dom
属性更新(体现在props
中)updatePayload
,供commitWork
阶段使用