performSyncWorkOnRoot中有一个非常重要的方法 exitStatus = renderRootSync(root, lanes),继续深入,这里的workLoopSync是关键
function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; executionContext |= RenderContext; var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack // and prepare a fresh one. Otherwise we‘ll continue where we left off. if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { prepareFreshStack(root, lanes); startWorkOnPendingInteractions(root, lanes); } var prevInteractions = pushInteractions(root); { markRenderStarted(lanes); } do { try { workLoopSync(); break; } catch (thrownValue) { handleError(root, thrownValue); } } while (true); resetContextDependencies(); { popInteractions(prevInteractions); } executionContext = prevExecutionContext; popDispatcher(prevDispatcher); if (workInProgress !== null) { // This is a sync render, so we should have finished the whole tree. { { throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." ); } } } { markRenderStopped(); } // Set this to null to indicate there‘s no in-progress render. workInProgressRoot = null; workInProgressRootRenderLanes = NoLanes; return workInProgressRootExitStatus; }
workLoopSync
function workLoopSync() { // Already timed out, so perform work without checking if we need to yield. while (workInProgress !== null) { performUnitOfWork(workInProgress); } }
function performUnitOfWork(unitOfWork) { // The current, flushed, state of this fiber is the alternate. Ideally // nothing should rely on this, but relying on it here means that we don‘t // need an additional field on the work in progress. var current = unitOfWork.alternate; setCurrentFiber(unitOfWork); var next; if ( (unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); next = beginWork$1(current, unitOfWork, subtreeRenderLanes); stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); } else { next = beginWork$1(current, unitOfWork, subtreeRenderLanes); } resetCurrentFiber(); unitOfWork.memoizedProps = unitOfWork.pendingProps; if (next === null) { // If this doesn‘t spawn new work, complete the current work. completeUnitOfWork(unitOfWork); } else { workInProgress = next; } ReactCurrentOwner$2.current = null; }