functionrenderRootSync(root, lanes) { // ...... if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { { if (isDevToolsPresent) { var memoizedUpdaters = root.memoizedUpdaters;
if (memoizedUpdaters.size > 0) { restorePendingUpdaters(root, workInProgressRootRenderLanes); memoizedUpdaters.clear(); } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set. // If we bailout on this work, we'll move them back (like above). // It's important to move them now in case the work spawns more work at the same priority with different updaters. // That way we can keep the current update and future updates separate.
functionbeginWork(current, workInProgress, renderLanes) { var updateLanes = workInProgress.lanes; { if (workInProgress._debugNeedsRemount && current !== null) { // This will restart the begin phase with a new fiber. return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes)); } }
// 当前的workInProgress树上正在工作的单元对应的alternate对应的Fiber节点 if (current !== null) { var oldProps = current.memoizedProps; var newProps = workInProgress.pendingProps;
functionChildReconciler(shouldTrackSideEffects) { // ......其他节点的diff算法 // 这里只展示单一节点的diff算法的源码 functionreconcileSingleElement(returnFiber, currentFirstChild, element, lanes) { var key = element.key; var child = currentFirstChild;
while (child !== null) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { var elementType = element.type;
if (elementType === REACT_FRAGMENT_TYPE) { if (child.tag === Fragment) { deleteRemainingChildren(returnFiber, child.sibling); var existing = useFiber(child, element.props.children); existing.return = returnFiber;
return existing; } } else { if (child.elementType === elementType || ( // Keep this check inline so it only runs on the false path: isCompatibleFamilyForHotReloading(child, element) ) || // Lazy types should reconcile their resolved type. // We need to do this after the Hot Reloading check above, // because hot reloading has different semantics than prod because // it doesn't resuspend. So we can't let the call below suspend. typeof elementType === 'object' && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === child.type) { deleteRemainingChildren(returnFiber, child.sibling);
functionplaceSingleChild(newFiber) { // This is simpler for the single child case. We only need to do a // placement for inserting new children. if (shouldTrackSideEffects && newFiber.alternate === null) { newFiber.flags |= Placement; }
functionbailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { if (current !== null) { workInProgress.dependencies = current.dependencies; } { stopProfilerTimerIfRunning(); } markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work.
// 当前的workInProgress树上正在工作的单元对应的alternate对应的Fiber节点 if (current !== null) { var oldProps = current.memoizedProps; var newProps = workInProgress.pendingProps;
workInProgress.flags = current.flags & StaticMask; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so // it cannot be shared with the current fiber.
var currentDependencies = current.dependencies; workInProgress.dependencies = currentDependencies === null ? null : { lanes: currentDependencies.lanes, firstContext: currentDependencies.firstContext }; // These will be overridden during the parent's reconciliation