Skip to content

Commit b0f13e5

Browse files
authored
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 60e63b9 commit b0f13e5

File tree

4 files changed

+170
-26
lines changed

4 files changed

+170
-26
lines changed

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

+23-3
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,
@@ -2602,15 +2603,22 @@ export function commitPassiveMountEffects(
26022603
root: FiberRoot,
26032604
finishedWork: Fiber,
26042605
committedLanes: Lanes,
2606+
committedTransitions: Array<Transition> | null,
26052607
): void {
26062608
nextEffect = finishedWork;
2607-
commitPassiveMountEffects_begin(finishedWork, root, committedLanes);
2609+
commitPassiveMountEffects_begin(
2610+
finishedWork,
2611+
root,
2612+
committedLanes,
2613+
committedTransitions,
2614+
);
26082615
}
26092616

26102617
function commitPassiveMountEffects_begin(
26112618
subtreeRoot: Fiber,
26122619
root: FiberRoot,
26132620
committedLanes: Lanes,
2621+
committedTransitions: Array<Transition> | null,
26142622
) {
26152623
while (nextEffect !== null) {
26162624
const fiber = nextEffect;
@@ -2619,7 +2627,12 @@ function commitPassiveMountEffects_begin(
26192627
firstChild.return = fiber;
26202628
nextEffect = firstChild;
26212629
} else {
2622-
commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes);
2630+
commitPassiveMountEffects_complete(
2631+
subtreeRoot,
2632+
root,
2633+
committedLanes,
2634+
committedTransitions,
2635+
);
26232636
}
26242637
}
26252638
}
@@ -2628,14 +2641,20 @@ function commitPassiveMountEffects_complete(
26282641
subtreeRoot: Fiber,
26292642
root: FiberRoot,
26302643
committedLanes: Lanes,
2644+
committedTransitions: Array<Transition> | null,
26312645
) {
26322646
while (nextEffect !== null) {
26332647
const fiber = nextEffect;
26342648

26352649
if ((fiber.flags & Passive) !== NoFlags) {
26362650
setCurrentDebugFiberInDEV(fiber);
26372651
try {
2638-
commitPassiveMountOnFiber(root, fiber, committedLanes);
2652+
commitPassiveMountOnFiber(
2653+
root,
2654+
fiber,
2655+
committedLanes,
2656+
committedTransitions,
2657+
);
26392658
} catch (error) {
26402659
captureCommitPhaseError(fiber, fiber.return, error);
26412660
}
@@ -2662,6 +2681,7 @@ function commitPassiveMountOnFiber(
26622681
finishedRoot: FiberRoot,
26632682
finishedWork: Fiber,
26642683
committedLanes: Lanes,
2684+
committedTransitions: Array<Transition> | null,
26652685
): void {
26662686
switch (finishedWork.tag) {
26672687
case FunctionComponent:

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

+23-3
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,
@@ -2602,15 +2603,22 @@ export function commitPassiveMountEffects(
26022603
root: FiberRoot,
26032604
finishedWork: Fiber,
26042605
committedLanes: Lanes,
2606+
committedTransitions: Array<Transition> | null,
26052607
): void {
26062608
nextEffect = finishedWork;
2607-
commitPassiveMountEffects_begin(finishedWork, root, committedLanes);
2609+
commitPassiveMountEffects_begin(
2610+
finishedWork,
2611+
root,
2612+
committedLanes,
2613+
committedTransitions,
2614+
);
26082615
}
26092616

26102617
function commitPassiveMountEffects_begin(
26112618
subtreeRoot: Fiber,
26122619
root: FiberRoot,
26132620
committedLanes: Lanes,
2621+
committedTransitions: Array<Transition> | null,
26142622
) {
26152623
while (nextEffect !== null) {
26162624
const fiber = nextEffect;
@@ -2619,7 +2627,12 @@ function commitPassiveMountEffects_begin(
26192627
firstChild.return = fiber;
26202628
nextEffect = firstChild;
26212629
} else {
2622-
commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes);
2630+
commitPassiveMountEffects_complete(
2631+
subtreeRoot,
2632+
root,
2633+
committedLanes,
2634+
committedTransitions,
2635+
);
26232636
}
26242637
}
26252638
}
@@ -2628,14 +2641,20 @@ function commitPassiveMountEffects_complete(
26282641
subtreeRoot: Fiber,
26292642
root: FiberRoot,
26302643
committedLanes: Lanes,
2644+
committedTransitions: Array<Transition> | null,
26312645
) {
26322646
while (nextEffect !== null) {
26332647
const fiber = nextEffect;
26342648

26352649
if ((fiber.flags & Passive) !== NoFlags) {
26362650
setCurrentDebugFiberInDEV(fiber);
26372651
try {
2638-
commitPassiveMountOnFiber(root, fiber, committedLanes);
2652+
commitPassiveMountOnFiber(
2653+
root,
2654+
fiber,
2655+
committedLanes,
2656+
committedTransitions,
2657+
);
26392658
} catch (error) {
26402659
captureCommitPhaseError(fiber, fiber.return, error);
26412660
}
@@ -2662,6 +2681,7 @@ function commitPassiveMountOnFiber(
26622681
finishedRoot: FiberRoot,
26632682
finishedWork: Fiber,
26642683
committedLanes: Lanes,
2684+
committedTransitions: Array<Transition> | null,
26652685
): void {
26662686
switch (finishedWork.tag) {
26672687
case FunctionComponent:

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

+62-10
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)