Skip to content

Commit a627c17

Browse files
lunaruanrickhanlonii
authored andcommitted
add pendingPassiveTransitions (#24320)
Add pendingPassiveTransitions work loop module level variable. Because workInProgressTransitions might change before we process it in the passive effects, we introduce a new variable, pendingPassiveTransitions, where we store the transitions until we can actually process them in the commit phase.
1 parent 905ecec commit a627c17

File tree

4 files changed

+170
-26
lines changed

4 files changed

+170
-26
lines changed

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

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import type {OffscreenState} from './ReactFiberOffscreenComponent';
2626
import type {HookFlags} from './ReactHookEffectTags';
2727
import type {Cache} from './ReactFiberCacheComponent.new';
2828
import type {RootState} from './ReactFiberRoot.new';
29+
import type {Transition} from './ReactFiberTracingMarkerComponent.new';
2930

3031
import {
3132
enableCreateEventHandleAPI,
@@ -2622,15 +2623,22 @@ export function commitPassiveMountEffects(
26222623
root: FiberRoot,
26232624
finishedWork: Fiber,
26242625
committedLanes: Lanes,
2626+
committedTransitions: Array<Transition> | null,
26252627
): void {
26262628
nextEffect = finishedWork;
2627-
commitPassiveMountEffects_begin(finishedWork, root, committedLanes);
2629+
commitPassiveMountEffects_begin(
2630+
finishedWork,
2631+
root,
2632+
committedLanes,
2633+
committedTransitions,
2634+
);
26282635
}
26292636

26302637
function commitPassiveMountEffects_begin(
26312638
subtreeRoot: Fiber,
26322639
root: FiberRoot,
26332640
committedLanes: Lanes,
2641+
committedTransitions: Array<Transition> | null,
26342642
) {
26352643
while (nextEffect !== null) {
26362644
const fiber = nextEffect;
@@ -2639,7 +2647,12 @@ function commitPassiveMountEffects_begin(
26392647
firstChild.return = fiber;
26402648
nextEffect = firstChild;
26412649
} else {
2642-
commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes);
2650+
commitPassiveMountEffects_complete(
2651+
subtreeRoot,
2652+
root,
2653+
committedLanes,
2654+
committedTransitions,
2655+
);
26432656
}
26442657
}
26452658
}
@@ -2648,14 +2661,20 @@ function commitPassiveMountEffects_complete(
26482661
subtreeRoot: Fiber,
26492662
root: FiberRoot,
26502663
committedLanes: Lanes,
2664+
committedTransitions: Array<Transition> | null,
26512665
) {
26522666
while (nextEffect !== null) {
26532667
const fiber = nextEffect;
26542668

26552669
if ((fiber.flags & Passive) !== NoFlags) {
26562670
setCurrentDebugFiberInDEV(fiber);
26572671
try {
2658-
commitPassiveMountOnFiber(root, fiber, committedLanes);
2672+
commitPassiveMountOnFiber(
2673+
root,
2674+
fiber,
2675+
committedLanes,
2676+
committedTransitions,
2677+
);
26592678
} catch (error) {
26602679
captureCommitPhaseError(fiber, fiber.return, error);
26612680
}
@@ -2682,6 +2701,7 @@ function commitPassiveMountOnFiber(
26822701
finishedRoot: FiberRoot,
26832702
finishedWork: Fiber,
26842703
committedLanes: Lanes,
2704+
committedTransitions: Array<Transition> | null,
26852705
): void {
26862706
switch (finishedWork.tag) {
26872707
case FunctionComponent:

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

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import type {OffscreenState} from './ReactFiberOffscreenComponent';
2626
import type {HookFlags} from './ReactHookEffectTags';
2727
import type {Cache} from './ReactFiberCacheComponent.old';
2828
import type {RootState} from './ReactFiberRoot.old';
29+
import type {Transition} from './ReactFiberTracingMarkerComponent.old';
2930

3031
import {
3132
enableCreateEventHandleAPI,
@@ -2622,15 +2623,22 @@ export function commitPassiveMountEffects(
26222623
root: FiberRoot,
26232624
finishedWork: Fiber,
26242625
committedLanes: Lanes,
2626+
committedTransitions: Array<Transition> | null,
26252627
): void {
26262628
nextEffect = finishedWork;
2627-
commitPassiveMountEffects_begin(finishedWork, root, committedLanes);
2629+
commitPassiveMountEffects_begin(
2630+
finishedWork,
2631+
root,
2632+
committedLanes,
2633+
committedTransitions,
2634+
);
26282635
}
26292636

26302637
function commitPassiveMountEffects_begin(
26312638
subtreeRoot: Fiber,
26322639
root: FiberRoot,
26332640
committedLanes: Lanes,
2641+
committedTransitions: Array<Transition> | null,
26342642
) {
26352643
while (nextEffect !== null) {
26362644
const fiber = nextEffect;
@@ -2639,7 +2647,12 @@ function commitPassiveMountEffects_begin(
26392647
firstChild.return = fiber;
26402648
nextEffect = firstChild;
26412649
} else {
2642-
commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes);
2650+
commitPassiveMountEffects_complete(
2651+
subtreeRoot,
2652+
root,
2653+
committedLanes,
2654+
committedTransitions,
2655+
);
26432656
}
26442657
}
26452658
}
@@ -2648,14 +2661,20 @@ function commitPassiveMountEffects_complete(
26482661
subtreeRoot: Fiber,
26492662
root: FiberRoot,
26502663
committedLanes: Lanes,
2664+
committedTransitions: Array<Transition> | null,
26512665
) {
26522666
while (nextEffect !== null) {
26532667
const fiber = nextEffect;
26542668

26552669
if ((fiber.flags & Passive) !== NoFlags) {
26562670
setCurrentDebugFiberInDEV(fiber);
26572671
try {
2658-
commitPassiveMountOnFiber(root, fiber, committedLanes);
2672+
commitPassiveMountOnFiber(
2673+
root,
2674+
fiber,
2675+
committedLanes,
2676+
committedTransitions,
2677+
);
26592678
} catch (error) {
26602679
captureCommitPhaseError(fiber, fiber.return, error);
26612680
}
@@ -2682,6 +2701,7 @@ function commitPassiveMountOnFiber(
26822701
finishedRoot: FiberRoot,
26832702
finishedWork: Fiber,
26842703
committedLanes: Lanes,
2704+
committedTransitions: Array<Transition> | null,
26852705
): void {
26862706
switch (finishedWork.tag) {
26872707
case FunctionComponent:

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

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ let rootWithPendingPassiveEffects: FiberRoot | null = null;
392392
let pendingPassiveEffectsLanes: Lanes = NoLanes;
393393
let pendingPassiveProfilerEffects: Array<Fiber> = [];
394394
let pendingPassiveEffectsRemainingLanes: Lanes = NoLanes;
395+
let pendingPassiveTransitions: Array<Transition> | null = null;
395396

396397
// Use these to prevent an infinite loop of nested updates
397398
const NESTED_UPDATE_LIMIT = 50;
@@ -1075,7 +1076,11 @@ function finishConcurrentRender(root, exitStatus, lanes) {
10751076
case RootErrored: {
10761077
// We should have already attempted to retry this tree. If we reached
10771078
// this point, it errored again. Commit it.
1078-
commitRoot(root, workInProgressRootRecoverableErrors);
1079+
commitRoot(
1080+
root,
1081+
workInProgressRootRecoverableErrors,
1082+
workInProgressTransitions,
1083+
);
10791084
break;
10801085
}
10811086
case RootSuspended: {
@@ -1115,14 +1120,23 @@ function finishConcurrentRender(root, exitStatus, lanes) {
11151120
// lower priority work to do. Instead of committing the fallback
11161121
// immediately, wait for more data to arrive.
11171122
root.timeoutHandle = scheduleTimeout(
1118-
commitRoot.bind(null, root, workInProgressRootRecoverableErrors),
1123+
commitRoot.bind(
1124+
null,
1125+
root,
1126+
workInProgressRootRecoverableErrors,
1127+
workInProgressTransitions,
1128+
),
11191129
msUntilTimeout,
11201130
);
11211131
break;
11221132
}
11231133
}
11241134
// The work expired. Commit immediately.
1125-
commitRoot(root, workInProgressRootRecoverableErrors);
1135+
commitRoot(
1136+
root,
1137+
workInProgressRootRecoverableErrors,
1138+
workInProgressTransitions,
1139+
);
11261140
break;
11271141
}
11281142
case RootSuspendedWithDelay: {
@@ -1153,20 +1167,33 @@ function finishConcurrentRender(root, exitStatus, lanes) {
11531167
// Instead of committing the fallback immediately, wait for more data
11541168
// to arrive.
11551169
root.timeoutHandle = scheduleTimeout(
1156-
commitRoot.bind(null, root, workInProgressRootRecoverableErrors),
1170+
commitRoot.bind(
1171+
null,
1172+
root,
1173+
workInProgressRootRecoverableErrors,
1174+
workInProgressTransitions,
1175+
),
11571176
msUntilTimeout,
11581177
);
11591178
break;
11601179
}
11611180
}
11621181

11631182
// Commit the placeholder.
1164-
commitRoot(root, workInProgressRootRecoverableErrors);
1183+
commitRoot(
1184+
root,
1185+
workInProgressRootRecoverableErrors,
1186+
workInProgressTransitions,
1187+
);
11651188
break;
11661189
}
11671190
case RootCompleted: {
11681191
// The work completed. Ready to commit.
1169-
commitRoot(root, workInProgressRootRecoverableErrors);
1192+
commitRoot(
1193+
root,
1194+
workInProgressRootRecoverableErrors,
1195+
workInProgressTransitions,
1196+
);
11701197
break;
11711198
}
11721199
default: {
@@ -1290,7 +1317,11 @@ function performSyncWorkOnRoot(root) {
12901317
const finishedWork: Fiber = (root.current.alternate: any);
12911318
root.finishedWork = finishedWork;
12921319
root.finishedLanes = lanes;
1293-
commitRoot(root, workInProgressRootRecoverableErrors);
1320+
commitRoot(
1321+
root,
1322+
workInProgressRootRecoverableErrors,
1323+
workInProgressTransitions,
1324+
);
12941325

12951326
// Before exiting, make sure there's a callback scheduled for the next
12961327
// pending level.
@@ -1972,7 +2003,11 @@ function completeUnitOfWork(unitOfWork: Fiber): void {
19722003
}
19732004
}
19742005

1975-
function commitRoot(root: FiberRoot, recoverableErrors: null | Array<mixed>) {
2006+
function commitRoot(
2007+
root: FiberRoot,
2008+
recoverableErrors: null | Array<mixed>,
2009+
transitions: Array<Transition> | null,
2010+
) {
19762011
// TODO: This no longer makes any sense. We already wrap the mutation and
19772012
// layout phases. Should be able to remove.
19782013
const previousUpdateLanePriority = getCurrentUpdatePriority();
@@ -1981,7 +2016,12 @@ function commitRoot(root: FiberRoot, recoverableErrors: null | Array<mixed>) {
19812016
try {
19822017
ReactCurrentBatchConfig.transition = null;
19832018
setCurrentUpdatePriority(DiscreteEventPriority);
1984-
commitRootImpl(root, recoverableErrors, previousUpdateLanePriority);
2019+
commitRootImpl(
2020+
root,
2021+
recoverableErrors,
2022+
transitions,
2023+
previousUpdateLanePriority,
2024+
);
19852025
} finally {
19862026
ReactCurrentBatchConfig.transition = prevTransition;
19872027
setCurrentUpdatePriority(previousUpdateLanePriority);
@@ -1993,6 +2033,7 @@ function commitRoot(root: FiberRoot, recoverableErrors: null | Array<mixed>) {
19932033
function commitRootImpl(
19942034
root: FiberRoot,
19952035
recoverableErrors: null | Array<mixed>,
2036+
transitions: Array<Transition> | null,
19962037
renderPriorityLevel: EventPriority,
19972038
) {
19982039
do {
@@ -2088,6 +2129,13 @@ function commitRootImpl(
20882129
if (!rootDoesHavePassiveEffects) {
20892130
rootDoesHavePassiveEffects = true;
20902131
pendingPassiveEffectsRemainingLanes = remainingLanes;
2132+
// workInProgressTransitions might be overwritten, so we want
2133+
// to store it in pendingPassiveTransitions until they get processed
2134+
// We need to pass this through as an argument to commitRoot
2135+
// because workInProgressTransitions might have changed between
2136+
// the previous render and commit if we throttle the commit
2137+
// with setTimeout
2138+
pendingPassiveTransitions = transitions;
20912139
scheduleCallback(NormalSchedulerPriority, () => {
20922140
flushPassiveEffects();
20932141
// This render triggered passive effects: release the root cache pool
@@ -2408,6 +2456,10 @@ function flushPassiveEffectsImpl() {
24082456
return false;
24092457
}
24102458

2459+
// Cache and clear the transitions flag
2460+
const transitions = pendingPassiveTransitions;
2461+
pendingPassiveTransitions = null;
2462+
24112463
const root = rootWithPendingPassiveEffects;
24122464
const lanes = pendingPassiveEffectsLanes;
24132465
rootWithPendingPassiveEffects = null;
@@ -2437,7 +2489,7 @@ function flushPassiveEffectsImpl() {
24372489
executionContext |= CommitContext;
24382490

24392491
commitPassiveUnmountEffects(root.current);
2440-
commitPassiveMountEffects(root, root.current, lanes);
2492+
commitPassiveMountEffects(root, root.current, lanes, transitions);
24412493

24422494
// TODO: Move to commitPassiveMountEffects
24432495
if (enableProfilerTimer && enableProfilerCommitHooks) {

0 commit comments

Comments
 (0)