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