You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
nextEffect=firstEffect;// 循环遍历effectListdo{try{// 调用commitMutationEffects()commitMutationEffects(root,renderPriorityLevel);}catch(error){invariant(nextEffect!==null,'Should be working on an effect.');captureCommitPhaseError(nextEffect,error);nextEffect=nextEffect.nextEffect;}}while(nextEffect!==null);
root.current=finishedWork;// current Fiber树切换nextEffect=firstEffect;// 遍历effectListdo{try{// 执行 commitLayoutEffects()commitLayoutEffects(root,lanes);}catch(error){invariant(nextEffect!==null,"Should be working on an effect.");captureCommitPhaseError(nextEffect,error);nextEffect=nextEffect.nextEffect;}}while(nextEffect!==null);nextEffect=null;
React 技术揭秘学习笔记
参考文章:React技术揭秘
导航
render阶段
performSyncWorkOnRoot() || performConcurrentWorkOnRoot()
performUnitOfWork()
beginWork()
reconcileChildren()
mountChildFibers()
reconcileChildFibers()
completeWork()
commit阶段
commitRoot(fiberRootNode)
内容
before mutation
遍历
effectList
并调用commitBeforeMutationEffects
函数处理。commitBeforeMutationEffects()
整体可以分为三部分:
DOM节点
渲染/删除后的autoFocus
、blur
逻辑。getSnapshotBeforeUpdate
生命周期钩子。useEffect
。❗️注意:是调度useEffect
而不是调用。mutation
遍历
effectList
并调用commitMutationEffects
函数处理。commitMutationEffects
commitMutationEffects
会遍历effectList
,对每个Fiber节点
执行如下三个操作:ContentReset effectTag
重置文字节点ref
effectTag
分别处理,其中effectTag
包括(Placement
|Update
|Deletion
|Hydrating[服务端渲染相关]
)Placement effect & commitPlacement
Placement effectTag
: 插入标记,意味着该Fiber节点
对应的DOM节点
需要插入到页面中。调用
commitPlacement
方法执行Placement effectTag
操作。Update effect & commitWork
Update effectTag
: 更新标记,意味着该Fiber节点
需要更新并将结果映射为DOM节点
插入到页面中。调用
commitWork
方法执行Update effectTag
操作。commitWork()
会根据Fiber.tag
分别处理不同的Fiber类型
。✅ FunctionComponent mutation
当
fiber.tag
为FunctionComponent
,会调用commitHookEffectListUnmount
。该方法会遍历effectList
,执行所有useLayoutEffect hook
的销毁函数。✅ HostComponent mutation
当
fiber.tag
为HostComponent
,会调用commitUpdate
。最终会在updateDOMProperties
(opens new window)中将render阶段 completeWork
(opens new window)中为Fiber节点
赋值的updateQueue
对应的内容渲染在页面上。Deletion effect & commitDeletion
Deletion effectTag
: 删除标记,意味着该Fiber节点
对应的DOM节点
需要从页面中删除。调用
commitDeletion
方法执行Deletion effectTag
操作。commitDeletion 方法会执行如下操作:
Fiber节点
及其子孙Fiber节点
中fiber.tag
为ClassComponent
的componentWillUnmount
(opens new window)生命周期钩子,从页面移除Fiber节点
对应DOM节点
ref
useEffect
的销毁函数layout
遍历
effectList
,执行commitLayoutEffects()
函数。该阶段的代码都是在
DOM
渲染完成(mutation阶段
完成)后执行的。该阶段触发的生命周期钩子和hook
可以直接访问到已经改变后的DOM
。root.current = finishedWork
在双缓存机制一节介绍过,
workInProgress Fiber树
在commit阶段
完成渲染后会变为current Fiber树
。root.current = finishedWork
的作用就是切换fiberRootNode
指向的current Fiber树
。以该行代码为界,分隔成
mutation阶段
和layout阶段
,分割出了两大类生命周期函数:componentWillUnmount
会在mutation阶段
执行。此时current Fiber树
还指向前一次更新的Fiber树
,在生命周期钩子内获取的DOM
还是更新前的。componentDidMount
和componentDidUpdate
会在layout阶段
执行。此时current Fiber树
已经指向更新后的Fiber树
,在生命周期钩子内获取的DOM
就是更新后的。commitLayoutEffects
commitLayoutEffects
一共做了两件事:生命周期钩子
和hook
相关操作, 触发状态更新
的this.setState
如果赋值了第二个参数回调函数
,也会在此时调用。)commitLayoutEffectOnFiber
生命周期钩子
hook
相关操作状态更新
的this.setState
如果赋值了第二个参数回调函数
,也会在此时调用。commitLayoutEffectOnFiber
方法会根据fiber.tag
对不同类型的节点分别处理。ClassComponent
,他会通过current === null?
区分是mount
还是update
,调用componentDidMount
或componentDidUpdate
FunctionComponent
及相关类型,他会调用useLayoutEffect hook
的回调函数
,调度useEffect
的销毁
与回调
函数HostRoot
,即rootFiber
,如果赋值了第三个参数回调函数
,也会在此时调用。The text was updated successfully, but these errors were encountered: