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)
递的过程 是一个 深度优先 的过程