Skip to content

Commit

Permalink
Updated PR according to comments
Browse files Browse the repository at this point in the history
  • Loading branch information
lunaruan committed Apr 5, 2022
1 parent 6197bf9 commit b6dcc6f
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 127 deletions.
68 changes: 35 additions & 33 deletions packages/react-reconciler/src/ReactFiberBeginWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ import {
markSkippedUpdateLanes,
getWorkInProgressRoot,
pushRenderLanes,
setRootPendingSuspenseBoundaries,
} from './ReactFiberWorkLoop.new';
import {setWorkInProgressVersion} from './ReactMutableSource.new';
import {pushCacheProvider, CacheContext} from './ReactFiberCacheComponent.new';
Expand Down Expand Up @@ -654,6 +653,7 @@ function updateOffscreenComponent(
// Rendering a hidden tree.
if ((workInProgress.mode & ConcurrentMode) === NoMode) {
// In legacy sync mode, don't defer the subtree. Render it now.
// TODO: Consider how Offscreen should work with transitions in the future
const nextState: OffscreenState = {
baseLanes: NoLanes,
cachePool: null,
Expand Down Expand Up @@ -751,14 +751,21 @@ function updateOffscreenComponent(

subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes);

if (enableCache || enableTransitionTracing) {
let prevCachePool = null;
if (enableCache) {
// If the render that spawned this one accessed the cache pool, resume
// using the same cache. Unless the parent changed, since that means
// there was a refresh.
const prevCachePool = prevState.cachePool;
const transitions = prevState.transitions;
pushTransition(workInProgress, prevCachePool, transitions);
prevCachePool = prevState.cachePool;
}

let transitions = null;
if (enableTransitionTracing) {
transitions = prevState.transitions;
}

pushTransition(workInProgress, prevCachePool, transitions);

// Since we're not hidden anymore, reset the state
workInProgress.memoizedState = null;
} else {
Expand Down Expand Up @@ -1337,9 +1344,7 @@ function updateHostRoot(current, workInProgress, renderLanes) {
const nextState: RootState = workInProgress.memoizedState;
const root: FiberRoot = workInProgress.stateNode;

if (enableCache || enableTransitionTracing) {
pushRootTransition(workInProgress, root, renderLanes);
}
pushRootTransition(workInProgress, root, renderLanes);

if (enableCache) {
const nextCache: Cache = workInProgress.memoizedState.cache;
Expand All @@ -1350,15 +1355,7 @@ function updateHostRoot(current, workInProgress, renderLanes) {
}
}

let pendingSuspenseBoundaries = nextState.pendingSuspenseBoundaries;
if (enableTransitionTracing) {
if (prevState.pendingSuspenseBoundaries === null) {
pendingSuspenseBoundaries = new Map();
}
// TODO(luna) change to pushPendingSuspenseBoundaries
// once we add tracing markers
setRootPendingSuspenseBoundaries(pendingSuspenseBoundaries);
}
const pendingSuspenseBoundaries = nextState.pendingSuspenseBoundaries || null;

// Caution: React DevTools currently depends on this property
// being called "element".
Expand All @@ -1373,7 +1370,7 @@ function updateHostRoot(current, workInProgress, renderLanes) {
element: nextChildren,
isDehydrated: false,
cache: nextState.cache,
pendingSuspenseBoundaries: pendingSuspenseBoundaries,
pendingSuspenseBoundaries,
transitions: nextState.transitions,
};
const updateQueue: UpdateQueue<RootState> = (workInProgress.updateQueue: any);
Expand Down Expand Up @@ -1453,7 +1450,7 @@ function updateHostRoot(current, workInProgress, renderLanes) {
element: nextChildren,
isDehydrated: nextState.isDehydrated,
cache: nextState.cache,
pendingSuspenseBoundaries: pendingSuspenseBoundaries,
pendingSuspenseBoundaries,
transitions: nextState.transitions,
};

Expand Down Expand Up @@ -2132,6 +2129,8 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {

pushSuspenseContext(workInProgress, suspenseContext);

const root = getWorkInProgressRoot();

// OK, the next part is confusing. We're about to reconcile the Suspense
// boundary's children. This involves some custom reconciliation logic. Two
// main reasons this is so complicated.
Expand Down Expand Up @@ -2172,7 +2171,6 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
}
}
}

const nextPrimaryChildren = nextProps.children;
const nextFallbackChildren = nextProps.fallback;

Expand All @@ -2188,6 +2186,18 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
renderLanes,
);
workInProgress.memoizedState = SUSPENDED_MARKER;
if (enableTransitionTracing) {
const currentTransitions = getSuspendedTransitions();
if (currentTransitions !== null) {
const primaryChildUpdateQueue: OffscreenQueue = {
transitions: currentTransitions,
rootMemoizedState:
root === null ? null : root.current.memoizedState,
};
primaryChildFragment.updateQueue = primaryChildUpdateQueue;
}
}

return fallbackFragment;
} else if (
enableCPUSuspense &&
Expand Down Expand Up @@ -2314,6 +2324,8 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
if (currentTransitions !== null) {
const primaryChildUpdateQueue: OffscreenQueue = {
transitions: currentTransitions,
rootMemoizedState:
root === null ? null : root.current.memoizedState,
};
primaryChildFragment.updateQueue = primaryChildUpdateQueue;
}
Expand Down Expand Up @@ -2365,6 +2377,8 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
if (currentTransitions !== null) {
const primaryChildUpdateQueue: OffscreenQueue = {
transitions: currentTransitions,
rootMemoizedState:
root === null ? null : root.current.memoizedState,
};
primaryChildFragment.updateQueue = primaryChildUpdateQueue;
}
Expand Down Expand Up @@ -3623,25 +3637,13 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
case HostRoot:
pushHostRootContext(workInProgress);
const root: FiberRoot = workInProgress.stateNode;
if (enableCache || enableTransitionTracing) {
pushRootTransition(workInProgress, root, renderLanes);
}
pushRootTransition(workInProgress, root, renderLanes);

if (enableCache) {
const cache: Cache = current.memoizedState.cache;
pushCacheProvider(workInProgress, cache);
}

if (enableTransitionTracing) {
const pendingSuspenseBoundaries =
workInProgress.memoizedState.pendingSuspenseBoundaries;
// TODO(luna) change to pushPendingSuspenseBoundaries
// once we add tracing markers
if (pendingSuspenseBoundaries) {
setRootPendingSuspenseBoundaries(pendingSuspenseBoundaries);
}
}

resetHydrationState();
break;
case HostComponent:
Expand Down
79 changes: 58 additions & 21 deletions packages/react-reconciler/src/ReactFiberCommitWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ import type {
import type {HookFlags} from './ReactHookEffectTags';
import type {Cache} from './ReactFiberCacheComponent.new';
import type {RootState} from './ReactFiberRoot.new';
import type {
Transition,
PendingSuspenseBoundaries,
} from './ReactFiberTracingMarkerComponent.new';

import {
enableCreateEventHandleAPI,
Expand Down Expand Up @@ -141,8 +145,6 @@ import {
restorePendingUpdaters,
addTransitionStartCallbackToPendingTransition,
addTransitionCompleteCallbackToPendingTransition,
getWorkInProgressTransitions,
getRootPendingSuspenseBoundaries,
} from './ReactFiberWorkLoop.new';
import {
NoFlags as NoHookEffect,
Expand Down Expand Up @@ -1064,7 +1066,8 @@ function reappearLayoutEffectsOnFiber(node: Fiber) {
function addOrRemovePendingBoundariesOnRoot(
finishedWork: Fiber,
name: string | null,
stateNode: OffscreenInstance,
offscreenInstance: OffscreenInstance,
rootPendingBoundaries: PendingSuspenseBoundaries | null,
) {
// This function adds suspense boundaries to the root
// or tracing marker that are a part of their subtrees
Expand All @@ -1089,12 +1092,11 @@ function addOrRemovePendingBoundariesOnRoot(
const wasHidden = prevState !== null;
const isHidden = nextState !== null;

const rootPendingBoundaries = getRootPendingSuspenseBoundaries();
if (rootPendingBoundaries !== null) {
if (finishedWork.alternate === null) {
// Initial mount
if (isHidden) {
rootPendingBoundaries.set(stateNode, {
rootPendingBoundaries.set(offscreenInstance, {
name,
});
}
Expand All @@ -1103,13 +1105,13 @@ function addOrRemovePendingBoundariesOnRoot(
// The suspense boundary went from hidden to visible. Remove
// the boundary from the pending suspense boundaries set
// if it's there
if (rootPendingBoundaries.has(stateNode)) {
rootPendingBoundaries.delete(stateNode);
if (rootPendingBoundaries.has(offscreenInstance)) {
rootPendingBoundaries.delete(offscreenInstance);
}
} else if (!wasHidden && isHidden) {
// The suspense boundaries was just hidden. Add the boundary
// to the pending boundary set if it's there
rootPendingBoundaries.set(stateNode, {
rootPendingBoundaries.set(offscreenInstance, {
name,
});
}
Expand Down Expand Up @@ -2657,15 +2659,22 @@ export function commitPassiveMountEffects(
root: FiberRoot,
finishedWork: Fiber,
committedLanes: Lanes,
transitions: Array<Transition> | null,
): void {
nextEffect = finishedWork;
commitPassiveMountEffects_begin(finishedWork, root, committedLanes);
commitPassiveMountEffects_begin(
finishedWork,
root,
committedLanes,
transitions,
);
}

function commitPassiveMountEffects_begin(
subtreeRoot: Fiber,
root: FiberRoot,
committedLanes: Lanes,
currentTransitions: Array<Transition> | null,
) {
while (nextEffect !== null) {
const fiber = nextEffect;
Expand All @@ -2674,7 +2683,12 @@ function commitPassiveMountEffects_begin(
ensureCorrectReturnPointer(firstChild, fiber);
nextEffect = firstChild;
} else {
commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes);
commitPassiveMountEffects_complete(
subtreeRoot,
root,
committedLanes,
currentTransitions,
);
}
}
}
Expand All @@ -2683,6 +2697,7 @@ function commitPassiveMountEffects_complete(
subtreeRoot: Fiber,
root: FiberRoot,
committedLanes: Lanes,
currentTransitions: Array<Transition> | null,
) {
while (nextEffect !== null) {
const fiber = nextEffect;
Expand All @@ -2693,7 +2708,6 @@ function commitPassiveMountEffects_complete(
case HostRoot: {
// Get the transitions that were initiatized during the render
// and add a start transition callback for each of them
const currentTransitions = getWorkInProgressTransitions();
if (currentTransitions != null) {
if (fiber.memoizedState.transitions === null) {
fiber.memoizedState.transitions = [];
Expand Down Expand Up @@ -2731,7 +2745,10 @@ function commitPassiveMountEffects_complete(
transition !== null &&
!filteredTransitions.has(transition)
) {
if (pendingSuspenseBoundaries.size === 0) {
if (
pendingSuspenseBoundaries === null ||
pendingSuspenseBoundaries.size === 0
) {
addTransitionCompleteCallbackToPendingTransition({
transitionName: transition.name,
startTime: transition.startTime,
Expand All @@ -2746,7 +2763,10 @@ function commitPassiveMountEffects_complete(
// If there are no more pending suspense boundaries we
// clear the transitions because they are all complete. Otherwise
// we store the transitions where we remove all duplicates
if (pendingSuspenseBoundaries.size === 0) {
if (
pendingSuspenseBoundaries === null ||
pendingSuspenseBoundaries.size === 0
) {
state.transitions = null;
} else {
state.transitions = [Array.from(filteredTransitions)];
Expand All @@ -2757,12 +2777,17 @@ function commitPassiveMountEffects_complete(
case OffscreenComponent: {
if (enableTransitionTracing) {
const isFallback = fiber.memoizedState;
let props;
if (isFallback) {
props = fiber.pendingProps;
const queue = (fiber.updateQueue: any);
const queue = (fiber.updateQueue: any);
let pendingSuspenseBoundaries = null;
if (queue !== null) {
const rootMemoizedState = queue.rootMemoizedState;
if (rootMemoizedState.pendingSuspenseBoundaries === null) {
rootMemoizedState.pendingSuspenseBoundaries = new Map();
}
pendingSuspenseBoundaries =
rootMemoizedState.pendingSuspenseBoundaries;

if (queue !== null) {
if (isFallback) {
const transitions = queue.transitions;
const prevTransitions = fiber.memoizedState.transitions;
if (transitions != null) {
Expand All @@ -2775,16 +2800,28 @@ function commitPassiveMountEffects_complete(
}
}
}
} else {
props = fiber.memoizedProps;
}

let name = null;
const parent = fiber.return;
if (
parent !== null &&
parent.tag === SuspenseComponent &&
parent.memoizedProps.name
) {
name = parent.memoizedProps.name;
}
// We use stateNode on the Offscreen component as a stable object
// that doesnt change from render to render. This way we can
// distinguish between different Offscreen instances (vs. the same
// Offscreen instance with different fibers)
const stateNode = fiber.stateNode;

addOrRemovePendingBoundariesOnRoot(
fiber,
props.name || null,
name,
stateNode,
pendingSuspenseBoundaries,
);
}
break;
Expand Down
8 changes: 2 additions & 6 deletions packages/react-reconciler/src/ReactFiberCompleteWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -874,9 +874,7 @@ function completeWork(
}
}

if (enableCache || enableTransitionTracing) {
popRootTransition(workInProgress, fiberRoot, renderLanes);
}
popRootTransition(workInProgress, fiberRoot, renderLanes);

if (enableCache) {
let previousCache: Cache | null = null;
Expand Down Expand Up @@ -1598,9 +1596,7 @@ function completeWork(
}
}

if (enableCache || enableTransitionTracing) {
popTransition(workInProgress, current);
}
popTransition(workInProgress, current);

return null;
}
Expand Down
Loading

0 comments on commit b6dcc6f

Please sign in to comment.