Skip to content

Commit 50b43b0

Browse files
committed
commit work
1 parent c5e039d commit 50b43b0

File tree

1 file changed

+157
-12
lines changed

1 file changed

+157
-12
lines changed

packages/react-reconciler/src/ReactFiberCommitWork.new.js

Lines changed: 157 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,17 @@ import type {SuspenseState} from './ReactFiberSuspenseComponent.new';
2222
import type {UpdateQueue} from './ReactUpdateQueue.new';
2323
import type {FunctionComponentUpdateQueue} from './ReactFiberHooks.new';
2424
import type {Wakeable} from 'shared/ReactTypes';
25-
import type {OffscreenState} from './ReactFiberOffscreenComponent';
25+
import type {
26+
OffscreenState,
27+
OffscreenInstance,
28+
} from './ReactFiberOffscreenComponent';
2629
import type {HookFlags} from './ReactHookEffectTags';
2730
import type {Cache} from './ReactFiberCacheComponent.new';
2831
import type {RootState} from './ReactFiberRoot.new';
29-
import type {Transition} from './ReactFiberTracingMarkerComponent.new';
32+
import type {
33+
Transition,
34+
PendingSuspenseBoundaries,
35+
} from './ReactFiberTracingMarkerComponent.new';
3036

3137
import {
3238
enableCreateEventHandleAPI,
@@ -62,6 +68,7 @@ import {
6268
OffscreenComponent,
6369
LegacyHiddenComponent,
6470
CacheComponent,
71+
TracingMarkerComponent,
6572
} from './ReactWorkTags';
6673
import {detachDeletedInstance} from './ReactFiberHostConfig';
6774
import {
@@ -1001,7 +1008,8 @@ function commitLayoutEffectOnFiber(
10011008
case IncompleteClassComponent:
10021009
case ScopeComponent:
10031010
case OffscreenComponent:
1004-
case LegacyHiddenComponent: {
1011+
case LegacyHiddenComponent:
1012+
case TracingMarkerComponent: {
10051013
break;
10061014
}
10071015

@@ -1066,6 +1074,77 @@ function reappearLayoutEffectsOnFiber(node: Fiber) {
10661074
}
10671075
}
10681076

1077+
function commitTransitionProgress(
1078+
finishedRoot: FiberRoot,
1079+
offscreenFiber: Fiber,
1080+
) {
1081+
// This function adds suspense boundaries to the root
1082+
// or tracing marker's pendingSuspenseBoundaries map.
1083+
// When a suspense boundary goes from a resolved to a fallback
1084+
// state we add the boundary to the map, and when it goes from
1085+
// a fallback to a resolved state, we remove the boundary from
1086+
// the map.
1087+
1088+
// We use stateNode on the Offscreen component as a stable object
1089+
// that doesnt change from render to render. This way we can
1090+
// distinguish between different Offscreen instances (vs. the same
1091+
// Offscreen instance with different fibers)
1092+
const offscreenInstance: OffscreenInstance = offscreenFiber.stateNode;
1093+
1094+
let prevState: SuspenseState | null = null;
1095+
const previousFiber = offscreenFiber.alternate;
1096+
if (previousFiber !== null && previousFiber.memoizedState !== null) {
1097+
prevState = previousFiber.memoizedState;
1098+
}
1099+
const nextState: SuspenseState | null = offscreenFiber.memoizedState;
1100+
1101+
const wasHidden = prevState !== null;
1102+
const isHidden = nextState !== null;
1103+
1104+
const rootState: RootState = finishedRoot.current.memoizedState;
1105+
// TODO(luna) move pendingSuspenseBoundaries and transitions from
1106+
// HostRoot fiber to FiberRoot
1107+
const rootPendingBoundaries = rootState.pendingSuspenseBoundaries;
1108+
1109+
// If there is a name on the suspense boundary, store that in
1110+
// the pending boundaries.
1111+
let name = null;
1112+
const parent = offscreenFiber.return;
1113+
if (
1114+
parent !== null &&
1115+
parent.tag === SuspenseComponent &&
1116+
parent.memoizedProps.unstable_name
1117+
) {
1118+
name = parent.memoizedProps.unstable_name;
1119+
}
1120+
1121+
if (rootPendingBoundaries !== null) {
1122+
if (previousFiber === null) {
1123+
// Initial mount
1124+
if (isHidden) {
1125+
rootPendingBoundaries.set(offscreenInstance, {
1126+
name,
1127+
});
1128+
}
1129+
} else {
1130+
if (wasHidden && !isHidden) {
1131+
// The suspense boundary went from hidden to visible. Remove
1132+
// the boundary from the pending suspense boundaries set
1133+
// if it's there
1134+
if (rootPendingBoundaries.has(offscreenInstance)) {
1135+
rootPendingBoundaries.delete(offscreenInstance);
1136+
}
1137+
} else if (!wasHidden && isHidden) {
1138+
// The suspense boundaries was just hidden. Add the boundary
1139+
// to the pending boundary set if it's there
1140+
rootPendingBoundaries.set(offscreenInstance, {
1141+
name,
1142+
});
1143+
}
1144+
}
1145+
}
1146+
}
1147+
10691148
function hideOrUnhideAllChildren(finishedWork, isHidden) {
10701149
// Only hide or unhide the top-most host nodes.
10711150
let hostSubtreeRoot = null;
@@ -2747,22 +2826,53 @@ function commitPassiveMountOnFiber(
27472826
}
27482827

27492828
if (enableTransitionTracing) {
2750-
if (committedTransitions !== null) {
2829+
// Get the transitions that were initiatized during the render
2830+
// and add a start transition callback for each of them
2831+
const state = finishedWork.memoizedState;
2832+
if (state.transitions === null) {
2833+
state.transitions = new Set([]);
2834+
}
2835+
const pendingTransitions = state.transitions;
2836+
2837+
if (committedTransitions != null) {
27512838
committedTransitions.forEach(transition => {
2752-
// TODO(luna) Do we want to log TransitionStart in the startTransition callback instead?
27532839
addTransitionStartCallbackToPendingTransition({
27542840
transitionName: transition.name,
27552841
startTime: transition.startTime,
27562842
});
2757-
2758-
addTransitionCompleteCallbackToPendingTransition({
2759-
transitionName: transition.name,
2760-
startTime: transition.startTime,
2761-
});
2843+
pendingTransitions.add(transition);
27622844
});
27632845

27642846
clearTransitionsForLanes(finishedRoot, committedLanes);
2765-
finishedWork.memoizedState.transitions = null;
2847+
}
2848+
2849+
const pendingSuspenseBoundaries = state.pendingSuspenseBoundaries;
2850+
const processedTransitions = new Set();
2851+
// process the lazy transitions list by filtering duplicate transitions
2852+
// and calling the transition complete callback on all transitions
2853+
// if there are no more pending suspense boundaries
2854+
pendingTransitions.forEach(transition => {
2855+
if (!processedTransitions.has(transition)) {
2856+
if (
2857+
pendingSuspenseBoundaries === null ||
2858+
pendingSuspenseBoundaries.size === 0
2859+
) {
2860+
addTransitionCompleteCallbackToPendingTransition({
2861+
transitionName: transition.name,
2862+
startTime: transition.startTime,
2863+
});
2864+
}
2865+
processedTransitions.add(transition);
2866+
}
2867+
});
2868+
2869+
// If there are no more pending suspense boundaries we
2870+
// clear the transitions because they are all complete.
2871+
if (
2872+
pendingSuspenseBoundaries === null ||
2873+
pendingSuspenseBoundaries.size === 0
2874+
) {
2875+
state.transitions = null;
27662876
}
27672877
}
27682878
break;
@@ -2800,9 +2910,44 @@ function commitPassiveMountOnFiber(
28002910
}
28012911

28022912
if (enableTransitionTracing) {
2803-
// TODO: Add code to actually process the update queue
2913+
const isFallback = finishedWork.memoizedState;
2914+
const queue = (finishedWork.updateQueue: any);
2915+
const rootMemoizedState = finishedRoot.current.memoizedState;
2916+
2917+
if (queue !== null) {
2918+
// We have one instance of the pendingSuspenseBoundaries map.
2919+
// We only need one because we update it during the commit phase.
2920+
// We instantiate a new Map if we haven't already
2921+
if (rootMemoizedState.pendingSuspenseBoundaries === null) {
2922+
rootMemoizedState.pendingSuspenseBoundaries = new Map();
2923+
}
2924+
2925+
if (isFallback) {
2926+
const transitions = queue.transitions;
2927+
let prevTransitions = finishedWork.memoizedState.transitions;
2928+
// Add all the transitions saved in the update queue during
2929+
// the render phase (ie the transitions associated with this boundary)
2930+
// into the transitions set.
2931+
if (transitions != null) {
2932+
if (prevTransitions === null) {
2933+
// We only have one instance of the transitions set
2934+
// because we update it only during the commit phase. We
2935+
// will create the set on a as needed basis in the commit phase
2936+
finishedWork.memoizedState.transitions = prevTransitions = new Set();
2937+
}
2938+
2939+
transitions.forEach(transition => {
2940+
prevTransitions.add(transition);
2941+
});
2942+
}
2943+
}
2944+
}
2945+
2946+
commitTransitionProgress(finishedRoot, finishedWork);
2947+
28042948
finishedWork.updateQueue = null;
28052949
}
2950+
28062951
break;
28072952
}
28082953
case CacheComponent: {

0 commit comments

Comments
 (0)