Skip to content
On this page

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)

递的过程 是一个 深度优先 的过程