@@ -13,7 +13,6 @@ import type {Lanes, Lane} from './ReactFiberLane';
13
13
import type { ReactPriorityLevel } from './ReactInternalTypes' ;
14
14
import type { Interaction } from 'scheduler/src/Tracing' ;
15
15
import type { SuspenseState } from './ReactFiberSuspenseComponent.new' ;
16
- import type { Effect as HookEffect } from './ReactFiberHooks.new' ;
17
16
import type { StackCursor } from './ReactFiberStack.new' ;
18
17
import type { FunctionComponentUpdateQueue } from './ReactFiberHooks.new' ;
19
18
@@ -121,8 +120,16 @@ import {
121
120
import { LegacyRoot } from './ReactRootTags' ;
122
121
import {
123
122
NoFlags ,
124
- PerformedWork ,
125
123
Placement ,
124
+ PassiveStatic ,
125
+ Incomplete ,
126
+ HostEffectMask ,
127
+ Hydrating ,
128
+ BeforeMutationMask ,
129
+ MutationMask ,
130
+ LayoutMask ,
131
+ PassiveMask ,
132
+ PerformedWork ,
126
133
Update ,
127
134
PlacementAndUpdate ,
128
135
Deletion ,
@@ -131,11 +138,6 @@ import {
131
138
ContentReset ,
132
139
Snapshot ,
133
140
Callback ,
134
- Passive ,
135
- PassiveStatic ,
136
- Incomplete ,
137
- HostEffectMask ,
138
- Hydrating ,
139
141
HydratingAndUpdate ,
140
142
StaticMask ,
141
143
} from './ReactFiberFlags' ;
@@ -1956,7 +1958,35 @@ function commitRootImpl(root, renderPriorityLevel) {
1956
1958
firstEffect = finishedWork . firstEffect ;
1957
1959
}
1958
1960
1959
- if ( firstEffect !== null ) {
1961
+ // If there are pending passive effects, schedule a callback to process them.
1962
+ // Do this as early as possible, so it is queued before anything else that
1963
+ // might get scheduled in the commit phase. (See #16714.)
1964
+ if (
1965
+ ( finishedWork . subtreeFlags & PassiveMask ) !== NoFlags ||
1966
+ ( finishedWork . flags & PassiveMask ) !== NoFlags
1967
+ ) {
1968
+ rootDoesHavePassiveEffects = true ;
1969
+ scheduleCallback ( NormalSchedulerPriority , ( ) => {
1970
+ flushPassiveEffects ( ) ;
1971
+ return null ;
1972
+ } ) ;
1973
+ }
1974
+
1975
+ // Check if there are any effects in the whole tree.
1976
+ // TODO: This is left over from the effect list implementation, where we had
1977
+ // to check for the existence of `firstEffect` to satsify Flow. I think the
1978
+ // only other reason this optimization exists is because it affects profiling.
1979
+ // Reconsider whether this is necessary.
1980
+ const subtreeHasEffects =
1981
+ ( finishedWork . subtreeFlags &
1982
+ ( BeforeMutationMask | MutationMask | LayoutMask | PassiveMask ) ) !==
1983
+ NoFlags ;
1984
+ const rootHasEffect =
1985
+ ( finishedWork . flags &
1986
+ ( BeforeMutationMask | MutationMask | LayoutMask | PassiveMask ) ) !==
1987
+ NoFlags ;
1988
+
1989
+ if ( subtreeHasEffects || rootHasEffect ) {
1960
1990
let previousLanePriority ;
1961
1991
if ( decoupleUpdatePriorityFromScheduler ) {
1962
1992
previousLanePriority = getCurrentUpdateLanePriority ( ) ;
@@ -2275,17 +2305,6 @@ function commitBeforeMutationEffects() {
2275
2305
2276
2306
resetCurrentDebugFiberInDEV ( ) ;
2277
2307
}
2278
- if ( ( flags & Passive ) !== NoFlags ) {
2279
- // If there are passive effects, schedule a callback to flush at
2280
- // the earliest opportunity.
2281
- if ( ! rootDoesHavePassiveEffects ) {
2282
- rootDoesHavePassiveEffects = true ;
2283
- scheduleCallback ( NormalSchedulerPriority , ( ) => {
2284
- flushPassiveEffects ( ) ;
2285
- return null ;
2286
- } ) ;
2287
- }
2288
- }
2289
2308
nextEffect = nextEffect . nextEffect ;
2290
2309
}
2291
2310
}
@@ -2485,32 +2504,6 @@ export function enqueuePendingPassiveProfilerEffect(fiber: Fiber): void {
2485
2504
}
2486
2505
}
2487
2506
2488
- export function enqueuePendingPassiveHookEffectMount (
2489
- fiber : Fiber ,
2490
- effect : HookEffect ,
2491
- ) : void {
2492
- if ( ! rootDoesHavePassiveEffects ) {
2493
- rootDoesHavePassiveEffects = true ;
2494
- scheduleCallback ( NormalSchedulerPriority , ( ) => {
2495
- flushPassiveEffects ( ) ;
2496
- return null ;
2497
- } ) ;
2498
- }
2499
- }
2500
-
2501
- export function enqueuePendingPassiveHookEffectUnmount (
2502
- fiber : Fiber ,
2503
- effect : HookEffect ,
2504
- ) : void {
2505
- if ( ! rootDoesHavePassiveEffects ) {
2506
- rootDoesHavePassiveEffects = true ;
2507
- scheduleCallback ( NormalSchedulerPriority , ( ) => {
2508
- flushPassiveEffects ( ) ;
2509
- return null ;
2510
- } ) ;
2511
- }
2512
- }
2513
-
2514
2507
function flushPassiveEffectsImpl ( ) {
2515
2508
if ( rootWithPendingPassiveEffects === null ) {
2516
2509
return false ;
0 commit comments