Skip to content

Commit 5223a07

Browse files
author
Brian Vaughn
committed
Use effectTag to suppress unmounted state update warnings
dquote> dquote> Replace the separate current and alternate arrays with a new effect tag, PassiveUnmountPending, that we use to check for the case where a state update is scheduled for an unmoutned component that has a pending passive effect cleanup scheduled.
1 parent 57164f2 commit 5223a07

File tree

3 files changed

+53
-52
lines changed

3 files changed

+53
-52
lines changed

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

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ import {
116116
Snapshot,
117117
Callback,
118118
Passive,
119+
PassiveUnmountPending,
119120
Incomplete,
120121
HostEffectMask,
121122
Hydrating,
@@ -262,7 +263,6 @@ let pendingPassiveEffectsRenderPriority: ReactPriorityLevel = NoPriority;
262263
let pendingPassiveEffectsExpirationTime: ExpirationTime = NoWork;
263264
let pendingPassiveHookEffectsMount: Array<HookEffect | Fiber> = [];
264265
let pendingPassiveHookEffectsUnmount: Array<HookEffect | Fiber> = [];
265-
let pendingPassiveHookEffectsUnmountAlternatesDEV: Array<Fiber> = [];
266266
let pendingPassiveProfilerEffects: Array<Fiber> = [];
267267

268268
let rootsWithPendingDiscreteUpdates: Map<
@@ -2313,10 +2313,10 @@ export function enqueuePendingPassiveHookEffectUnmount(
23132313
pendingPassiveHookEffectsUnmount.push(effect, fiber);
23142314
if (__DEV__) {
23152315
if (deferPassiveEffectCleanupDuringUnmount) {
2316-
if (fiber.alternate !== null) {
2317-
// Alternate pointers get disconnected during unmount.
2318-
// Track alternates explicitly here to avoid warning about state updates for unmounted components.
2319-
pendingPassiveHookEffectsUnmountAlternatesDEV.push(fiber.alternate);
2316+
fiber.effectTag |= PassiveUnmountPending;
2317+
const alternate = fiber.alternate;
2318+
if (alternate !== null) {
2319+
alternate.effectTag |= PassiveUnmountPending;
23202320
}
23212321
}
23222322
}
@@ -2377,19 +2377,22 @@ function flushPassiveEffectsImpl() {
23772377
// First pass: Destroy stale passive effects.
23782378
const unmountEffects = pendingPassiveHookEffectsUnmount;
23792379
pendingPassiveHookEffectsUnmount = [];
2380-
if (__DEV__) {
2381-
if (
2382-
deferPassiveEffectCleanupDuringUnmount &&
2383-
runAllPassiveEffectDestroysBeforeCreates
2384-
) {
2385-
pendingPassiveHookEffectsUnmountAlternatesDEV = [];
2386-
}
2387-
}
23882380
for (let i = 0; i < unmountEffects.length; i += 2) {
23892381
const effect = ((unmountEffects[i]: any): HookEffect);
23902382
const fiber = ((unmountEffects[i + 1]: any): Fiber);
23912383
const destroy = effect.destroy;
23922384
effect.destroy = undefined;
2385+
2386+
if (__DEV__) {
2387+
if (deferPassiveEffectCleanupDuringUnmount) {
2388+
fiber.effectTag &= ~PassiveUnmountPending;
2389+
const alternate = fiber.alternate;
2390+
if (alternate !== null) {
2391+
alternate.effectTag &= ~PassiveUnmountPending;
2392+
}
2393+
}
2394+
}
2395+
23932396
if (typeof destroy === 'function') {
23942397
if (__DEV__) {
23952398
setCurrentDebugFiberInDEV(fiber);
@@ -2869,10 +2872,7 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
28692872
) {
28702873
// If there are pending passive effects unmounts for this Fiber,
28712874
// we can assume that they would have prevented this update.
2872-
if (
2873-
pendingPassiveHookEffectsUnmount.indexOf(fiber) >= 0 ||
2874-
pendingPassiveHookEffectsUnmountAlternatesDEV.indexOf(fiber) >= 0
2875-
) {
2875+
if ((fiber.effectTag & PassiveUnmountPending) !== NoEffect) {
28762876
return;
28772877
}
28782878
}

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

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ import {
116116
Snapshot,
117117
Callback,
118118
Passive,
119+
PassiveUnmountPending,
119120
Incomplete,
120121
HostEffectMask,
121122
Hydrating,
@@ -260,7 +261,6 @@ let pendingPassiveEffectsRenderPriority: ReactPriorityLevel = NoPriority;
260261
let pendingPassiveEffectsExpirationTime: ExpirationTime = NoWork;
261262
let pendingPassiveHookEffectsMount: Array<HookEffect | Fiber> = [];
262263
let pendingPassiveHookEffectsUnmount: Array<HookEffect | Fiber> = [];
263-
let pendingPassiveHookEffectsUnmountAlternatesDEV: Array<Fiber> = [];
264264
let pendingPassiveProfilerEffects: Array<Fiber> = [];
265265

266266
let rootsWithPendingDiscreteUpdates: Map<
@@ -2332,10 +2332,10 @@ export function enqueuePendingPassiveHookEffectUnmount(
23322332
pendingPassiveHookEffectsUnmount.push(effect, fiber);
23332333
if (__DEV__) {
23342334
if (deferPassiveEffectCleanupDuringUnmount) {
2335-
if (fiber.alternate !== null) {
2336-
// Alternate pointers get disconnected during unmount.
2337-
// Track alternates explicitly here to avoid warning about state updates for unmounted components.
2338-
pendingPassiveHookEffectsUnmountAlternatesDEV.push(fiber.alternate);
2335+
fiber.effectTag |= PassiveUnmountPending;
2336+
const alternate = fiber.alternate;
2337+
if (alternate !== null) {
2338+
alternate.effectTag |= PassiveUnmountPending;
23392339
}
23402340
}
23412341
}
@@ -2396,19 +2396,22 @@ function flushPassiveEffectsImpl() {
23962396
// First pass: Destroy stale passive effects.
23972397
const unmountEffects = pendingPassiveHookEffectsUnmount;
23982398
pendingPassiveHookEffectsUnmount = [];
2399-
if (__DEV__) {
2400-
if (
2401-
deferPassiveEffectCleanupDuringUnmount &&
2402-
runAllPassiveEffectDestroysBeforeCreates
2403-
) {
2404-
pendingPassiveHookEffectsUnmountAlternatesDEV = [];
2405-
}
2406-
}
24072399
for (let i = 0; i < unmountEffects.length; i += 2) {
24082400
const effect = ((unmountEffects[i]: any): HookEffect);
24092401
const fiber = ((unmountEffects[i + 1]: any): Fiber);
24102402
const destroy = effect.destroy;
24112403
effect.destroy = undefined;
2404+
2405+
if (__DEV__) {
2406+
if (deferPassiveEffectCleanupDuringUnmount) {
2407+
fiber.effectTag &= ~PassiveUnmountPending;
2408+
const alternate = fiber.alternate;
2409+
if (alternate !== null) {
2410+
alternate.effectTag &= ~PassiveUnmountPending;
2411+
}
2412+
}
2413+
}
2414+
24122415
if (typeof destroy === 'function') {
24132416
if (__DEV__) {
24142417
setCurrentDebugFiberInDEV(fiber);
@@ -2891,10 +2894,7 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
28912894
) {
28922895
// If there are pending passive effects unmounts for this Fiber,
28932896
// we can assume that they would have prevented this update.
2894-
if (
2895-
pendingPassiveHookEffectsUnmount.indexOf(fiber) >= 0 ||
2896-
pendingPassiveHookEffectsUnmountAlternatesDEV.indexOf(fiber) >= 0
2897-
) {
2897+
if ((fiber.effectTag & PassiveUnmountPending) !== NoEffect) {
28982898
return;
28992899
}
29002900
}

packages/react-reconciler/src/ReactSideEffectTags.js

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,29 @@
1010
export type SideEffectTag = number;
1111

1212
// Don't change these two values. They're used by React Dev Tools.
13-
export const NoEffect = /* */ 0b0000000000000;
14-
export const PerformedWork = /* */ 0b0000000000001;
13+
export const NoEffect = /* */ 0b00000000000000;
14+
export const PerformedWork = /* */ 0b00000000000001;
1515

1616
// You can change the rest (and add more).
17-
export const Placement = /* */ 0b0000000000010;
18-
export const Update = /* */ 0b0000000000100;
19-
export const PlacementAndUpdate = /* */ 0b0000000000110;
20-
export const Deletion = /* */ 0b0000000001000;
21-
export const ContentReset = /* */ 0b0000000010000;
22-
export const Callback = /* */ 0b0000000100000;
23-
export const DidCapture = /* */ 0b0000001000000;
24-
export const Ref = /* */ 0b0000010000000;
25-
export const Snapshot = /* */ 0b0000100000000;
26-
export const Passive = /* */ 0b0001000000000;
27-
export const Hydrating = /* */ 0b0010000000000;
28-
export const HydratingAndUpdate = /* */ 0b0010000000100;
17+
export const Placement = /* */ 0b00000000000010;
18+
export const Update = /* */ 0b00000000000100;
19+
export const PlacementAndUpdate = /* */ 0b00000000000110;
20+
export const Deletion = /* */ 0b00000000001000;
21+
export const ContentReset = /* */ 0b00000000010000;
22+
export const Callback = /* */ 0b00000000100000;
23+
export const DidCapture = /* */ 0b00000001000000;
24+
export const Ref = /* */ 0b00000010000000;
25+
export const Snapshot = /* */ 0b00000100000000;
26+
export const Passive = /* */ 0b00001000000000;
27+
export const PassiveUnmountPending = /* */ 0b10000000000000;
28+
export const Hydrating = /* */ 0b00010000000000;
29+
export const HydratingAndUpdate = /* */ 0b00010000000100;
2930

3031
// Passive & Update & Callback & Ref & Snapshot
31-
export const LifecycleEffectMask = /* */ 0b0001110100100;
32+
export const LifecycleEffectMask = /* */ 0b00001110100100;
3233

3334
// Union of all host effects
34-
export const HostEffectMask = /* */ 0b0011111111111;
35+
export const HostEffectMask = /* */ 0b00011111111111;
3536

36-
export const Incomplete = /* */ 0b0100000000000;
37-
export const ShouldCapture = /* */ 0b1000000000000;
37+
export const Incomplete = /* */ 0b00100000000000;
38+
export const ShouldCapture = /* */ 0b01000000000000;

0 commit comments

Comments
 (0)