Skip to content
Prev Previous commit
Next Next commit
Outline push/pop logic in renderRoot
I want to get rid of the the `isSync` argument to `renderRoot`, and
instead use separate functions for concurrent and synchronous render.

As a first step, this extracts the push/pop logic that happens before
and after the render phase into helper functions.
  • Loading branch information
acdlite committed Sep 23, 2019
commit 975636be7821cadfc682b902a09e862582cf58ec
72 changes: 41 additions & 31 deletions packages/react-reconciler/src/ReactFiberWorkLoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -1249,20 +1249,8 @@ function renderRoot(
if (workInProgress !== null) {
const prevExecutionContext = executionContext;
executionContext |= RenderContext;
let prevDispatcher = ReactCurrentDispatcher.current;
if (prevDispatcher === null) {
// The React isomorphic package does not include a default dispatcher.
// Instead the first renderer will lazily attach one, in order to give
// nicer error messages.
prevDispatcher = ContextOnlyDispatcher;
}
ReactCurrentDispatcher.current = ContextOnlyDispatcher;
let prevInteractions: Set<Interaction> | null = null;
if (enableSchedulerTracing) {
prevInteractions = __interactionsRef.current;
__interactionsRef.current = root.memoizedInteractions;
}

const prevDispatcher = pushDispatcher(root);
const prevInteractions = pushInteractions(root);
startWorkLoopTimer(workInProgress);

do {
Expand Down Expand Up @@ -1312,16 +1300,47 @@ function renderRoot(
workInProgress = completeUnitOfWork(sourceFiber);
}
} while (true);

executionContext = prevExecutionContext;
resetContextDependencies();
ReactCurrentDispatcher.current = prevDispatcher;
executionContext = prevExecutionContext;
popDispatcher(prevDispatcher);
if (enableSchedulerTracing) {
__interactionsRef.current = ((prevInteractions: any): Set<Interaction>);
popInteractions(((prevInteractions: any): Set<Interaction>));
}
}
}

function pushDispatcher(root) {
const prevDispatcher = ReactCurrentDispatcher.current;
ReactCurrentDispatcher.current = ContextOnlyDispatcher;
if (prevDispatcher === null) {
// The React isomorphic package does not include a default dispatcher.
// Instead the first renderer will lazily attach one, in order to give
// nicer error messages.
return ContextOnlyDispatcher;
} else {
return prevDispatcher;
}
}

function popDispatcher(prevDispatcher) {
ReactCurrentDispatcher.current = prevDispatcher;
}

function pushInteractions(root) {
if (enableSchedulerTracing) {
const prevInteractions: Set<Interaction> | null = __interactionsRef.current;
__interactionsRef.current = root.memoizedInteractions;
return prevInteractions;
}
return null;
}

function popInteractions(prevInteractions) {
if (enableSchedulerTracing) {
__interactionsRef.current = prevInteractions;
}
}

export function markCommitTimeOfFallback() {
globalMostRecentFallbackTime = now();
}
Expand Down Expand Up @@ -1760,11 +1779,7 @@ function commitRootImpl(root, renderPriorityLevel) {
if (firstEffect !== null) {
const prevExecutionContext = executionContext;
executionContext |= CommitContext;
let prevInteractions: Set<Interaction> | null = null;
if (enableSchedulerTracing) {
prevInteractions = __interactionsRef.current;
__interactionsRef.current = root.memoizedInteractions;
}
const prevInteractions = pushInteractions(root);

// Reset this to null before calling lifecycles
ReactCurrentOwner.current = null;
Expand Down Expand Up @@ -1882,7 +1897,7 @@ function commitRootImpl(root, renderPriorityLevel) {
requestPaint();

if (enableSchedulerTracing) {
__interactionsRef.current = ((prevInteractions: any): Set<Interaction>);
popInteractions(((prevInteractions: any): Set<Interaction>));
}
executionContext = prevExecutionContext;
} else {
Expand Down Expand Up @@ -2151,18 +2166,13 @@ export function flushPassiveEffects() {
}

function flushPassiveEffectsImpl(root, expirationTime) {
let prevInteractions: Set<Interaction> | null = null;
if (enableSchedulerTracing) {
prevInteractions = __interactionsRef.current;
__interactionsRef.current = root.memoizedInteractions;
}

invariant(
(executionContext & (RenderContext | CommitContext)) === NoContext,
'Cannot flush passive effects while already rendering.',
);
const prevExecutionContext = executionContext;
executionContext |= CommitContext;
const prevInteractions = pushInteractions(root);

// Note: This currently assumes there are no passive effects on the root
// fiber, because the root is not part of its own effect list. This could
Expand Down Expand Up @@ -2193,7 +2203,7 @@ function flushPassiveEffectsImpl(root, expirationTime) {
}

if (enableSchedulerTracing) {
__interactionsRef.current = ((prevInteractions: any): Set<Interaction>);
popInteractions(((prevInteractions: any): Set<Interaction>));
finishPendingInteractions(root, expirationTime);
}

Expand Down