Skip to content

Commit a634f55

Browse files
committed
commit work
1 parent babb031 commit a634f55

File tree

2 files changed

+171
-26
lines changed

2 files changed

+171
-26
lines changed

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

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ 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';
@@ -1099,6 +1102,7 @@ function commitTransitionProgress(
10991102
// TODO(luna) move pendingSuspenseBoundaries and transitions from
11001103
// HostRoot fiber to FiberRoot
11011104
const rootPendingBoundaries = rootState.pendingSuspenseBoundaries;
1105+
const rootTransitions = rootState.transitions;
11021106

11031107
// If there is a name on the suspense boundary, store that in
11041108
// the pending boundaries.
@@ -1136,6 +1140,15 @@ function commitTransitionProgress(
11361140
});
11371141
}
11381142
}
1143+
1144+
if (rootPendingBoundaries.size === 0 && rootTransitions !== null) {
1145+
rootTransitions.forEach(transition => {
1146+
addTransitionCompleteCallbackToPendingTransition({
1147+
transitionName: transition.name,
1148+
startTime: transition.startTime,
1149+
});
1150+
});
1151+
}
11391152
}
11401153
}
11411154

@@ -2827,7 +2840,9 @@ function commitPassiveMountOnFiber(
28272840
state.transitions = new Set([]);
28282841
}
28292842
const pendingTransitions = state.transitions;
2843+
const pendingSuspenseBoundaries = state.pendingSuspenseBoundaries;
28302844

2845+
// Initial render
28312846
if (committedTransitions != null) {
28322847
committedTransitions.forEach(transition => {
28332848
addTransitionStartCallbackToPendingTransition({
@@ -2837,28 +2852,20 @@ function commitPassiveMountOnFiber(
28372852
pendingTransitions.add(transition);
28382853
});
28392854

2840-
clearTransitionsForLanes(finishedRoot, committedLanes);
2841-
}
2842-
2843-
const pendingSuspenseBoundaries = state.pendingSuspenseBoundaries;
2844-
const processedTransitions = new Set();
2845-
// process the lazy transitions list by filtering duplicate transitions
2846-
// and calling the transition complete callback on all transitions
2847-
// if there are no more pending suspense boundaries
2848-
pendingTransitions.forEach(transition => {
2849-
if (!processedTransitions.has(transition)) {
2850-
if (
2851-
pendingSuspenseBoundaries === null ||
2852-
pendingSuspenseBoundaries.size === 0
2853-
) {
2855+
if (
2856+
pendingSuspenseBoundaries === null ||
2857+
pendingSuspenseBoundaries.size === 0
2858+
) {
2859+
pendingTransitions.forEach(transition => {
28542860
addTransitionCompleteCallbackToPendingTransition({
28552861
transitionName: transition.name,
28562862
startTime: transition.startTime,
28572863
});
2858-
}
2859-
processedTransitions.add(transition);
2864+
});
28602865
}
2861-
});
2866+
2867+
clearTransitionsForLanes(finishedRoot, committedLanes);
2868+
}
28622869

28632870
// If there are no more pending suspense boundaries we
28642871
// clear the transitions because they are all complete.

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

Lines changed: 146 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ import type {SuspenseState} from './ReactFiberSuspenseComponent.old';
2222
import type {UpdateQueue} from './ReactUpdateQueue.old';
2323
import type {FunctionComponentUpdateQueue} from './ReactFiberHooks.old';
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.old';
2831
import type {RootState} from './ReactFiberRoot.old';
@@ -62,6 +65,7 @@ import {
6265
OffscreenComponent,
6366
LegacyHiddenComponent,
6467
CacheComponent,
68+
TracingMarkerComponent,
6569
} from './ReactWorkTags';
6670
import {detachDeletedInstance} from './ReactFiberHostConfig';
6771
import {
@@ -1001,7 +1005,8 @@ function commitLayoutEffectOnFiber(
10011005
case IncompleteClassComponent:
10021006
case ScopeComponent:
10031007
case OffscreenComponent:
1004-
case LegacyHiddenComponent: {
1008+
case LegacyHiddenComponent:
1009+
case TracingMarkerComponent: {
10051010
break;
10061011
}
10071012

@@ -1066,6 +1071,77 @@ function reappearLayoutEffectsOnFiber(node: Fiber) {
10661071
}
10671072
}
10681073

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

27492825
if (enableTransitionTracing) {
2750-
if (committedTransitions !== null) {
2826+
// Get the transitions that were initiatized during the render
2827+
// and add a start transition callback for each of them
2828+
const state = finishedWork.memoizedState;
2829+
if (state.transitions === null) {
2830+
state.transitions = new Set([]);
2831+
}
2832+
const pendingTransitions = state.transitions;
2833+
2834+
if (committedTransitions != null) {
27512835
committedTransitions.forEach(transition => {
2752-
// TODO(luna) Do we want to log TransitionStart in the startTransition callback instead?
27532836
addTransitionStartCallbackToPendingTransition({
27542837
transitionName: transition.name,
27552838
startTime: transition.startTime,
27562839
});
2840+
pendingTransitions.add(transition);
2841+
});
27572842

2843+
clearTransitionsForLanes(finishedRoot, committedLanes);
2844+
}
2845+
2846+
const pendingSuspenseBoundaries = state.pendingSuspenseBoundaries;
2847+
// process the lazy transitions list by filtering duplicate transitions
2848+
// and calling the transition complete callback on all transitions
2849+
// if there are no more pending suspense boundaries
2850+
pendingTransitions.forEach(transition => {
2851+
if (
2852+
pendingSuspenseBoundaries === null ||
2853+
pendingSuspenseBoundaries.size === 0
2854+
) {
27582855
addTransitionCompleteCallbackToPendingTransition({
27592856
transitionName: transition.name,
27602857
startTime: transition.startTime,
27612858
});
2762-
});
2859+
}
2860+
});
27632861

2764-
clearTransitionsForLanes(finishedRoot, committedLanes);
2765-
finishedWork.memoizedState.transitions = null;
2862+
// If there are no more pending suspense boundaries we
2863+
// clear the transitions because they are all complete.
2864+
if (
2865+
pendingSuspenseBoundaries === null ||
2866+
pendingSuspenseBoundaries.size === 0
2867+
) {
2868+
state.transitions = null;
27662869
}
27672870
}
27682871
break;
@@ -2800,9 +2903,44 @@ function commitPassiveMountOnFiber(
28002903
}
28012904

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

0 commit comments

Comments
 (0)