Appearance
render 过程:将生成的 fiber
节点,构建成 fiber
节点树
js
// 同步更新
// performSyncWorkOnRoot会调用该方法
function workLoopSync() {
while (workInProgress !== null) {
performUnitOfWork(workInProgress);
}
}
// 异步更新
// performConcurrentWorkOnRoot会调用该方法
function workLoopConcurrent() {
while (workInProgress !== null && !shouldYield()) {
performUnitOfWork(workInProgress);
}
}
workInProgress
代表当前已创建的workInProgress fiber
performUnitOfWork
方法会创建 下一个Fiber节点
并赋值给 workInProgress
,并将workInProgress
与已创建的Fiber节点
连接起来构成Fiber树
render 阶段不渲染 DOM,生成 Fiber树 之后,通过
commit
阶段渲染 DOM 节点
React 渲染是一个递归的过程
递阶段mount流程(beginWork)
传入当前
Fiber
节点,创建返回 其第一个子节点的Fiber节点(注意是子节点的Fiber)!!!
performUnitOfWork
内部调用的是 beginWork
js
function beginWork(current, workInProgress, renderLanes) {
// ...
switch (workInProgress.tag) {
// 根据tag 采取不同的操作
case HostComponent:
// html 节点
return updateHostComponent(current, workInProgress, renderLanes);
}
}
function updateHostComponent(current, workInProgress, renderLanes) {
// 优化点:标记是否是纯文本节点
const isDirectTextChild = shouldSetTextContent(type, nextProps);
// 为当前 workInProgress 创建 子Fiber 节点
reconcileChildren(current, workInProgress, nextChildren, renderLanes)
return workInProgress.child
}
function reconcileChildren(current, workInProgress, nextChildren, renderLanes) {
// 根据当前 workInProgress 是否有 current,决定是否标记 flags
// flags 决定 FiberNode 的后续操作,比如挂载到页面上、或者更新
// 生成 childFiber 节点
if (current === null) {
workInProgress.child = mountChildFibers(...)
// ChildReconciler(false)
} else {
workInProgress.child = reconcileChildFibers(...)
// ChildReconciler(true)
}
}
// 两者都调用了 ChildReconciler(false/true)
// 其中传入参数标记是否需要标记 tag
// 其中 html 元素调用了 reconcileChildFibers
function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) {
// ... newChild 是子节点
if (isObject) {
// 子节点是对象
//...
switch (newChild.$$typeof) {
// 根据 子节点 的类型生成 子Fiber 节点
}
}
if (typeof newChild === 'string' || typeof newChild === 'number') {
// 子节点是单纯文本
}
if (isArray(newChild)){
// 子节点是 Fiber 数组
}
//...兜底操作
return deleteRemainingChildren(returnFiber, currentFirstChild);
}
调用链
reconcileChildFibers
-> reconcileSingleElement
-> createFiberFromElement
-> createFiberFromTypeAndProps
-> createFiber
最终 返回 createFiber
创建的 Fiber 节点(当前workInProgress 的第一个子节点Fiber)
递的过程 是一个 深度优先 的过程