Skip to content

Commit

Permalink
Use effectTag to suppress unmounted state update warnings
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Brian Vaughn committed Apr 17, 2020
1 parent 57164f2 commit 5223a07
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 52 deletions.
34 changes: 17 additions & 17 deletions packages/react-reconciler/src/ReactFiberWorkLoop.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ import {
Snapshot,
Callback,
Passive,
PassiveUnmountPending,
Incomplete,
HostEffectMask,
Hydrating,
Expand Down Expand Up @@ -262,7 +263,6 @@ let pendingPassiveEffectsRenderPriority: ReactPriorityLevel = NoPriority;
let pendingPassiveEffectsExpirationTime: ExpirationTime = NoWork;
let pendingPassiveHookEffectsMount: Array<HookEffect | Fiber> = [];
let pendingPassiveHookEffectsUnmount: Array<HookEffect | Fiber> = [];
let pendingPassiveHookEffectsUnmountAlternatesDEV: Array<Fiber> = [];
let pendingPassiveProfilerEffects: Array<Fiber> = [];

let rootsWithPendingDiscreteUpdates: Map<
Expand Down Expand Up @@ -2313,10 +2313,10 @@ export function enqueuePendingPassiveHookEffectUnmount(
pendingPassiveHookEffectsUnmount.push(effect, fiber);
if (__DEV__) {
if (deferPassiveEffectCleanupDuringUnmount) {
if (fiber.alternate !== null) {
// Alternate pointers get disconnected during unmount.
// Track alternates explicitly here to avoid warning about state updates for unmounted components.
pendingPassiveHookEffectsUnmountAlternatesDEV.push(fiber.alternate);
fiber.effectTag |= PassiveUnmountPending;
const alternate = fiber.alternate;
if (alternate !== null) {
alternate.effectTag |= PassiveUnmountPending;
}
}
}
Expand Down Expand Up @@ -2377,19 +2377,22 @@ function flushPassiveEffectsImpl() {
// First pass: Destroy stale passive effects.
const unmountEffects = pendingPassiveHookEffectsUnmount;
pendingPassiveHookEffectsUnmount = [];
if (__DEV__) {
if (
deferPassiveEffectCleanupDuringUnmount &&
runAllPassiveEffectDestroysBeforeCreates
) {
pendingPassiveHookEffectsUnmountAlternatesDEV = [];
}
}
for (let i = 0; i < unmountEffects.length; i += 2) {
const effect = ((unmountEffects[i]: any): HookEffect);
const fiber = ((unmountEffects[i + 1]: any): Fiber);
const destroy = effect.destroy;
effect.destroy = undefined;

if (__DEV__) {
if (deferPassiveEffectCleanupDuringUnmount) {
fiber.effectTag &= ~PassiveUnmountPending;
const alternate = fiber.alternate;
if (alternate !== null) {
alternate.effectTag &= ~PassiveUnmountPending;
}
}
}

if (typeof destroy === 'function') {
if (__DEV__) {
setCurrentDebugFiberInDEV(fiber);
Expand Down Expand Up @@ -2869,10 +2872,7 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
) {
// If there are pending passive effects unmounts for this Fiber,
// we can assume that they would have prevented this update.
if (
pendingPassiveHookEffectsUnmount.indexOf(fiber) >= 0 ||
pendingPassiveHookEffectsUnmountAlternatesDEV.indexOf(fiber) >= 0
) {
if ((fiber.effectTag & PassiveUnmountPending) !== NoEffect) {
return;
}
}
Expand Down
34 changes: 17 additions & 17 deletions packages/react-reconciler/src/ReactFiberWorkLoop.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ import {
Snapshot,
Callback,
Passive,
PassiveUnmountPending,
Incomplete,
HostEffectMask,
Hydrating,
Expand Down Expand Up @@ -260,7 +261,6 @@ let pendingPassiveEffectsRenderPriority: ReactPriorityLevel = NoPriority;
let pendingPassiveEffectsExpirationTime: ExpirationTime = NoWork;
let pendingPassiveHookEffectsMount: Array<HookEffect | Fiber> = [];
let pendingPassiveHookEffectsUnmount: Array<HookEffect | Fiber> = [];
let pendingPassiveHookEffectsUnmountAlternatesDEV: Array<Fiber> = [];
let pendingPassiveProfilerEffects: Array<Fiber> = [];

let rootsWithPendingDiscreteUpdates: Map<
Expand Down Expand Up @@ -2332,10 +2332,10 @@ export function enqueuePendingPassiveHookEffectUnmount(
pendingPassiveHookEffectsUnmount.push(effect, fiber);
if (__DEV__) {
if (deferPassiveEffectCleanupDuringUnmount) {
if (fiber.alternate !== null) {
// Alternate pointers get disconnected during unmount.
// Track alternates explicitly here to avoid warning about state updates for unmounted components.
pendingPassiveHookEffectsUnmountAlternatesDEV.push(fiber.alternate);
fiber.effectTag |= PassiveUnmountPending;
const alternate = fiber.alternate;
if (alternate !== null) {
alternate.effectTag |= PassiveUnmountPending;
}
}
}
Expand Down Expand Up @@ -2396,19 +2396,22 @@ function flushPassiveEffectsImpl() {
// First pass: Destroy stale passive effects.
const unmountEffects = pendingPassiveHookEffectsUnmount;
pendingPassiveHookEffectsUnmount = [];
if (__DEV__) {
if (
deferPassiveEffectCleanupDuringUnmount &&
runAllPassiveEffectDestroysBeforeCreates
) {
pendingPassiveHookEffectsUnmountAlternatesDEV = [];
}
}
for (let i = 0; i < unmountEffects.length; i += 2) {
const effect = ((unmountEffects[i]: any): HookEffect);
const fiber = ((unmountEffects[i + 1]: any): Fiber);
const destroy = effect.destroy;
effect.destroy = undefined;

if (__DEV__) {
if (deferPassiveEffectCleanupDuringUnmount) {
fiber.effectTag &= ~PassiveUnmountPending;
const alternate = fiber.alternate;
if (alternate !== null) {
alternate.effectTag &= ~PassiveUnmountPending;
}
}
}

if (typeof destroy === 'function') {
if (__DEV__) {
setCurrentDebugFiberInDEV(fiber);
Expand Down Expand Up @@ -2891,10 +2894,7 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
) {
// If there are pending passive effects unmounts for this Fiber,
// we can assume that they would have prevented this update.
if (
pendingPassiveHookEffectsUnmount.indexOf(fiber) >= 0 ||
pendingPassiveHookEffectsUnmountAlternatesDEV.indexOf(fiber) >= 0
) {
if ((fiber.effectTag & PassiveUnmountPending) !== NoEffect) {
return;
}
}
Expand Down
37 changes: 19 additions & 18 deletions packages/react-reconciler/src/ReactSideEffectTags.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,29 @@
export type SideEffectTag = number;

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

// You can change the rest (and add more).
export const Placement = /* */ 0b0000000000010;
export const Update = /* */ 0b0000000000100;
export const PlacementAndUpdate = /* */ 0b0000000000110;
export const Deletion = /* */ 0b0000000001000;
export const ContentReset = /* */ 0b0000000010000;
export const Callback = /* */ 0b0000000100000;
export const DidCapture = /* */ 0b0000001000000;
export const Ref = /* */ 0b0000010000000;
export const Snapshot = /* */ 0b0000100000000;
export const Passive = /* */ 0b0001000000000;
export const Hydrating = /* */ 0b0010000000000;
export const HydratingAndUpdate = /* */ 0b0010000000100;
export const Placement = /* */ 0b00000000000010;
export const Update = /* */ 0b00000000000100;
export const PlacementAndUpdate = /* */ 0b00000000000110;
export const Deletion = /* */ 0b00000000001000;
export const ContentReset = /* */ 0b00000000010000;
export const Callback = /* */ 0b00000000100000;
export const DidCapture = /* */ 0b00000001000000;
export const Ref = /* */ 0b00000010000000;
export const Snapshot = /* */ 0b00000100000000;
export const Passive = /* */ 0b00001000000000;
export const PassiveUnmountPending = /* */ 0b10000000000000;
export const Hydrating = /* */ 0b00010000000000;
export const HydratingAndUpdate = /* */ 0b00010000000100;

// Passive & Update & Callback & Ref & Snapshot
export const LifecycleEffectMask = /* */ 0b0001110100100;
export const LifecycleEffectMask = /* */ 0b00001110100100;

// Union of all host effects
export const HostEffectMask = /* */ 0b0011111111111;
export const HostEffectMask = /* */ 0b00011111111111;

export const Incomplete = /* */ 0b0100000000000;
export const ShouldCapture = /* */ 0b1000000000000;
export const Incomplete = /* */ 0b00100000000000;
export const ShouldCapture = /* */ 0b01000000000000;

0 comments on commit 5223a07

Please sign in to comment.