Skip to content

Commit eed8fa3

Browse files
committed
commit work
1 parent fea6f8d commit eed8fa3

File tree

1 file changed

+162
-11
lines changed

1 file changed

+162
-11
lines changed

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

Lines changed: 162 additions & 11 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,
@@ -63,6 +69,7 @@ import {
6369
OffscreenComponent,
6470
LegacyHiddenComponent,
6571
CacheComponent,
72+
TracingMarkerComponent,
6673
} from './ReactWorkTags';
6774
import {detachDeletedInstance} from './ReactFiberHostConfig';
6875
import {
@@ -1002,7 +1009,8 @@ function commitLayoutEffectOnFiber(
10021009
case IncompleteClassComponent:
10031010
case ScopeComponent:
10041011
case OffscreenComponent:
1005-
case LegacyHiddenComponent: {
1012+
case LegacyHiddenComponent:
1013+
case TracingMarkerComponent: {
10061014
break;
10071015
}
10081016

@@ -1067,6 +1075,77 @@ function reappearLayoutEffectsOnFiber(node: Fiber) {
10671075
}
10681076
}
10691077

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

27272806
if (enableTransitionTracing) {
2728-
if (committedTransitions !== null) {
2807+
// Get the transitions that were initiatized during the render
2808+
// and add a start transition callback for each of them
2809+
const state = finishedWork.memoizedState;
2810+
if (state.transitions === null) {
2811+
state.transitions = new Set([]);
2812+
}
2813+
const pendingTransitions = state.transitions;
2814+
2815+
if (committedTransitions != null) {
27292816
committedTransitions.forEach(transition => {
2730-
// TODO(luna) Do we want to log TransitionStart in the startTransition callback instead?
27312817
addTransitionStartCallbackToPendingTransition({
27322818
transitionName: transition.name,
27332819
startTime: transition.startTime,
27342820
});
2735-
2736-
addTransitionCompleteCallbackToPendingTransition({
2737-
transitionName: transition.name,
2738-
startTime: transition.startTime,
2739-
});
2821+
pendingTransitions.add(transition);
27402822
});
27412823

27422824
clearTransitionsForLanes(finishedRoot, committedLanes);
2743-
finishedWork.memoizedState.transitions = null;
2825+
}
2826+
2827+
const pendingSuspenseBoundaries = state.pendingSuspenseBoundaries;
2828+
const processedTransitions = new Set();
2829+
// process the lazy transitions list by filtering duplicate transitions
2830+
// and calling the transition complete callback on all transitions
2831+
// if there are no more pending suspense boundaries
2832+
pendingTransitions.forEach(transition => {
2833+
if (!processedTransitions.has(transition)) {
2834+
if (
2835+
pendingSuspenseBoundaries === null ||
2836+
pendingSuspenseBoundaries.size === 0
2837+
) {
2838+
addTransitionCompleteCallbackToPendingTransition({
2839+
transitionName: transition.name,
2840+
startTime: transition.startTime,
2841+
});
2842+
}
2843+
processedTransitions.add(transition);
2844+
}
2845+
});
2846+
2847+
// If there are no more pending suspense boundaries we
2848+
// clear the transitions because they are all complete. Otherwise
2849+
// we store the transitions where we remove all duplicates
2850+
if (
2851+
pendingSuspenseBoundaries === null ||
2852+
pendingSuspenseBoundaries.size === 0
2853+
) {
2854+
state.transitions = null;
27442855
}
27452856
}
27462857
break;
@@ -2776,6 +2887,46 @@ function commitPassiveMountOnFiber(
27762887
}
27772888
}
27782889
}
2890+
2891+
if (enableTransitionTracing) {
2892+
const isFallback = finishedWork.memoizedState;
2893+
const queue = (finishedWork.updateQueue: any);
2894+
const rootMemoizedState = finishedRoot.current.memoizedState;
2895+
2896+
if (queue !== null) {
2897+
// We have one instance of the pendingSuspenseBoundaries map.
2898+
// We only need one because we update it during the commit phase.
2899+
// We instantiate a new Map if we haven't already
2900+
if (rootMemoizedState.pendingSuspenseBoundaries === null) {
2901+
rootMemoizedState.pendingSuspenseBoundaries = new Map();
2902+
}
2903+
2904+
if (isFallback) {
2905+
const transitions = queue.transitions;
2906+
let prevTransitions = finishedWork.memoizedState.transitions;
2907+
// Add all the transitions saved in the update queue during
2908+
// the render phase (ie the transitions associated with this boundary)
2909+
// into the transitions set.
2910+
if (transitions != null) {
2911+
if (prevTransitions === null) {
2912+
// We only have one instance of the transitions set
2913+
// because we update it only during the commit phase. We
2914+
// will create the set on a as needed basis in the commit phase
2915+
finishedWork.memoizedState.transitions = prevTransitions = new Set();
2916+
}
2917+
2918+
transitions.forEach(transition => {
2919+
prevTransitions.add(transition);
2920+
});
2921+
}
2922+
}
2923+
}
2924+
2925+
addOrRemovePendingBoundariesOnRoot(finishedRoot, finishedWork);
2926+
2927+
finishedWork.updateQueue = null;
2928+
}
2929+
27792930
break;
27802931
}
27812932
case CacheComponent: {

0 commit comments

Comments
 (0)