@@ -14,7 +14,7 @@ import type {ReactPriorityLevel} from './SchedulerWithReactIntegration';
14
14
import type { Interaction } from 'scheduler/src/Tracing' ;
15
15
import type { SuspenseConfig } from './ReactFiberSuspenseConfig' ;
16
16
import type { SuspenseState } from './ReactFiberSuspenseComponent' ;
17
- import type { Hook } from './ReactFiberHooks' ;
17
+ import type { Effect as HookEffect , Hook } from './ReactFiberHooks' ;
18
18
19
19
import {
20
20
warnAboutDeprecatedLifecycles ,
@@ -133,8 +133,6 @@ import {
133
133
commitBeforeMutationLifeCycles as commitBeforeMutationEffectOnFiber ,
134
134
commitLifeCycles as commitLayoutEffectOnFiber ,
135
135
commitPassiveHookEffects ,
136
- commitPassiveHookUnmountEffects ,
137
- commitPassiveHookMountEffects ,
138
136
commitPlacement ,
139
137
commitWork ,
140
138
commitDeletion ,
@@ -260,7 +258,8 @@ let rootDoesHavePassiveEffects: boolean = false;
260
258
let rootWithPendingPassiveEffects : FiberRoot | null = null ;
261
259
let pendingPassiveEffectsRenderPriority : ReactPriorityLevel = NoPriority ;
262
260
let pendingPassiveEffectsExpirationTime : ExpirationTime = NoWork ;
263
- let pendingUnmountedPassiveEffectDestroyFunctions : Array < ( ) => void > = [ ] ;
261
+ let pendingPassiveHookEffectsMount : Array < HookEffect | Fiber > = [ ] ;
262
+ let pendingPassiveHookEffectsUnmount : Array < HookEffect | Fiber > = [ ] ;
264
263
265
264
let rootsWithPendingDiscreteUpdates : Map <
266
265
FiberRoot ,
@@ -2180,11 +2179,28 @@ export function flushPassiveEffects() {
2180
2179
}
2181
2180
}
2182
2181
2183
- export function enqueuePendingPassiveEffectDestroyFn (
2184
- destroy : ( ) = > void ,
2182
+ export function enqueuePendingPassiveHookEffectMount (
2183
+ fiber : Fiber ,
2184
+ effect : HookEffect ,
2185
+ ) : void {
2186
+ if ( deferPassiveEffectCleanupDuringUnmount ) {
2187
+ pendingPassiveHookEffectsMount . push ( effect , fiber ) ;
2188
+ if ( ! rootDoesHavePassiveEffects ) {
2189
+ rootDoesHavePassiveEffects = true ;
2190
+ scheduleCallback ( NormalPriority , ( ) => {
2191
+ flushPassiveEffects ( ) ;
2192
+ return null ;
2193
+ } ) ;
2194
+ }
2195
+ }
2196
+ }
2197
+
2198
+ export function enqueuePendingPassiveHookEffectUnmount (
2199
+ fiber : Fiber ,
2200
+ effect : HookEffect ,
2185
2201
) : void {
2186
2202
if ( deferPassiveEffectCleanupDuringUnmount ) {
2187
- pendingUnmountedPassiveEffectDestroyFunctions . push ( destroy ) ;
2203
+ pendingPassiveHookEffectsUnmount . push ( effect , fiber ) ;
2188
2204
if ( ! rootDoesHavePassiveEffects ) {
2189
2205
rootDoesHavePassiveEffects = true ;
2190
2206
scheduleCallback ( NormalPriority , ( ) => {
@@ -2195,6 +2211,11 @@ export function enqueuePendingPassiveEffectDestroyFn(
2195
2211
}
2196
2212
}
2197
2213
2214
+ function invokePassiveEffectCreate ( effect : HookEffect ) : void {
2215
+ const create = effect . create ;
2216
+ effect . destroy = create ( ) ;
2217
+ }
2218
+
2198
2219
function flushPassiveEffectsImpl ( ) {
2199
2220
if ( rootWithPendingPassiveEffects === null ) {
2200
2221
return false ;
@@ -2213,18 +2234,6 @@ function flushPassiveEffectsImpl() {
2213
2234
const prevInteractions = pushInteractions ( root ) ;
2214
2235
2215
2236
if ( deferPassiveEffectCleanupDuringUnmount ) {
2216
- // Flush any pending passive effect destroy functions that belong to
2217
- // components that were unmounted during the most recent commit.
2218
- for (
2219
- let i = 0 ;
2220
- i < pendingUnmountedPassiveEffectDestroyFunctions . length ;
2221
- i ++
2222
- ) {
2223
- const destroy = pendingUnmountedPassiveEffectDestroyFunctions [ i ] ;
2224
- invokeGuardedCallback ( null , destroy , null ) ;
2225
- }
2226
- pendingUnmountedPassiveEffectDestroyFunctions . length = 0 ;
2227
-
2228
2237
// It's important that ALL pending passive effect destroy functions are called
2229
2238
// before ANY passive effect create functions are called.
2230
2239
// Otherwise effects in sibling components might interfere with each other.
@@ -2233,70 +2242,58 @@ function flushPassiveEffectsImpl() {
2233
2242
// Layout effects have the same constraint.
2234
2243
2235
2244
// First pass: Destroy stale passive effects.
2236
- //
2237
- // Note: This currently assumes there are no passive effects on the root fiber
2238
- // because the root is not part of its own effect list.
2239
- // This could change in the future.
2240
- let effect = root . current . firstEffect ;
2241
- while ( effect !== null ) {
2242
- if ( __DEV__ ) {
2243
- setCurrentDebugFiberInDEV ( effect ) ;
2244
- invokeGuardedCallback (
2245
- null ,
2246
- commitPassiveHookUnmountEffects ,
2247
- null ,
2248
- effect ,
2249
- ) ;
2250
- if ( hasCaughtError ( ) ) {
2251
- invariant ( effect !== null , 'Should be working on an effect.' ) ;
2252
- const error = clearCaughtError ( ) ;
2253
- captureCommitPhaseError ( effect , error ) ;
2254
- }
2255
- resetCurrentDebugFiberInDEV ( ) ;
2256
- } else {
2257
- try {
2258
- commitPassiveHookUnmountEffects ( effect ) ;
2259
- } catch ( error ) {
2260
- invariant ( effect !== null , 'Should be working on an effect.' ) ;
2261
- captureCommitPhaseError ( effect , error ) ;
2245
+ let unmountEffects = pendingPassiveHookEffectsUnmount ;
2246
+ pendingPassiveHookEffectsUnmount = [ ] ;
2247
+ for ( let i = 0 ; i < unmountEffects . length ; i += 2 ) {
2248
+ const effect = ( ( unmountEffects [ i ] : any ) : HookEffect ) ;
2249
+ const fiber = ( ( unmountEffects [ i + 1 ] : any ) : Fiber ) ;
2250
+ const destroy = effect . destroy ;
2251
+ effect . destroy = undefined ;
2252
+ if ( typeof destroy === 'function' ) {
2253
+ if ( __DEV__ ) {
2254
+ setCurrentDebugFiberInDEV ( fiber ) ;
2255
+ invokeGuardedCallback ( null , destroy , null ) ;
2256
+ if ( hasCaughtError ( ) ) {
2257
+ invariant ( fiber !== null , 'Should be working on an effect.' ) ;
2258
+ const error = clearCaughtError ( ) ;
2259
+ captureCommitPhaseError ( fiber , error ) ;
2260
+ }
2261
+ resetCurrentDebugFiberInDEV ( ) ;
2262
+ } else {
2263
+ try {
2264
+ destroy ( ) ;
2265
+ } catch ( error ) {
2266
+ invariant ( fiber !== null , 'Should be working on an effect.' ) ;
2267
+ captureCommitPhaseError ( fiber , error ) ;
2268
+ }
2262
2269
}
2263
2270
}
2264
- effect = effect . nextEffect ;
2265
2271
}
2266
2272
2267
2273
// Second pass: Create new passive effects.
2268
- //
2269
- // Note: This currently assumes there are no passive effects on the root fiber
2270
- // because the root is not part of its own effect list.
2271
- // This could change in the future.
2272
- effect = root . current . firstEffect ;
2273
- while ( effect !== null ) {
2274
+ let mountEffects = pendingPassiveHookEffectsMount ;
2275
+ pendingPassiveHookEffectsMount = [ ] ;
2276
+ for ( let i = 0 ; i < mountEffects . length ; i += 2 ) {
2277
+ const effect = ( ( mountEffects [ i ] : any ) : HookEffect ) ;
2278
+ const fiber = ( ( mountEffects [ i + 1 ] : any ) : Fiber ) ;
2274
2279
if ( __DEV__ ) {
2275
- setCurrentDebugFiberInDEV ( effect ) ;
2276
- invokeGuardedCallback (
2277
- null ,
2278
- commitPassiveHookMountEffects ,
2279
- null ,
2280
- effect ,
2281
- ) ;
2280
+ setCurrentDebugFiberInDEV ( fiber ) ;
2281
+ invokeGuardedCallback ( null , invokePassiveEffectCreate , null , effect ) ;
2282
2282
if ( hasCaughtError ( ) ) {
2283
- invariant ( effect !== null , 'Should be working on an effect.' ) ;
2283
+ invariant ( fiber !== null , 'Should be working on an effect.' ) ;
2284
2284
const error = clearCaughtError ( ) ;
2285
- captureCommitPhaseError ( effect , error ) ;
2285
+ captureCommitPhaseError ( fiber , error ) ;
2286
2286
}
2287
2287
resetCurrentDebugFiberInDEV ( ) ;
2288
2288
} else {
2289
2289
try {
2290
- commitPassiveHookMountEffects ( effect ) ;
2290
+ const create = effect . create ;
2291
+ effect . destroy = create ( ) ;
2291
2292
} catch ( error ) {
2292
- invariant ( effect !== null , 'Should be working on an effect.' ) ;
2293
- captureCommitPhaseError ( effect , error ) ;
2293
+ invariant ( fiber !== null , 'Should be working on an effect.' ) ;
2294
+ captureCommitPhaseError ( fiber , error ) ;
2294
2295
}
2295
2296
}
2296
- const nextNextEffect = effect . nextEffect ;
2297
- // Remove nextEffect pointer to assist GC
2298
- effect . nextEffect = null ;
2299
- effect = nextNextEffect ;
2300
2297
}
2301
2298
} else {
2302
2299
// Note: This currently assumes there are no passive effects on the root fiber
0 commit comments