Split recent passive effects changes into 2 flags (#18030)

* Split recent passive effects changes into 2 flags

Separate flags can now be used to opt passive effects into:
1) Deferring destroy functions on unmount to subsequent passive effects flush
2) Running all destroy functions (for all fibers) before create functions

This allows us to test the less risky feature (2) separately from the more risky one.

* deferPassiveEffectCleanupDuringUnmount is ignored unless runAllPassiveEffectDestroysBeforeCreates is true
This commit is contained in:
Brian Vaughn
2020-02-18 14:19:43 -08:00
committed by GitHub
parent 7752179b50
commit 156e20e584
12 changed files with 5763 additions and 5464 deletions
+7 -3
View File
@@ -34,6 +34,7 @@ import {
enableFundamentalAPI,
enableSuspenseCallback,
enableScopeAPI,
runAllPassiveEffectDestroysBeforeCreates,
} from 'shared/ReactFeatureFlags';
import {
FunctionComponent,
@@ -398,7 +399,7 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
}
function schedulePassiveEffects(finishedWork: Fiber) {
if (deferPassiveEffectCleanupDuringUnmount) {
if (runAllPassiveEffectDestroysBeforeCreates) {
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
let lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
if (lastEffect !== null) {
@@ -456,7 +457,7 @@ function commitLifeCycles(
// by a create function in another component during the same commit.
commitHookEffectListMount(HookLayout | HookHasEffect, finishedWork);
if (deferPassiveEffectCleanupDuringUnmount) {
if (runAllPassiveEffectDestroysBeforeCreates) {
schedulePassiveEffects(finishedWork);
}
return;
@@ -795,7 +796,10 @@ function commitUnmount(
if (lastEffect !== null) {
const firstEffect = lastEffect.next;
if (deferPassiveEffectCleanupDuringUnmount) {
if (
deferPassiveEffectCleanupDuringUnmount &&
runAllPassiveEffectDestroysBeforeCreates
) {
let effect = firstEffect;
do {
const {destroy, tag} = effect;
+4 -4
View File
@@ -18,7 +18,7 @@ import type {Effect as HookEffect} from './ReactFiberHooks';
import {
warnAboutDeprecatedLifecycles,
deferPassiveEffectCleanupDuringUnmount,
runAllPassiveEffectDestroysBeforeCreates,
enableUserTimingAPI,
enableSuspenseServerRenderer,
replayFailedUnitOfWorkWithInvokeGuardedCallback,
@@ -2174,7 +2174,7 @@ export function enqueuePendingPassiveHookEffectMount(
fiber: Fiber,
effect: HookEffect,
): void {
if (deferPassiveEffectCleanupDuringUnmount) {
if (runAllPassiveEffectDestroysBeforeCreates) {
pendingPassiveHookEffectsMount.push(effect, fiber);
if (!rootDoesHavePassiveEffects) {
rootDoesHavePassiveEffects = true;
@@ -2190,7 +2190,7 @@ export function enqueuePendingPassiveHookEffectUnmount(
fiber: Fiber,
effect: HookEffect,
): void {
if (deferPassiveEffectCleanupDuringUnmount) {
if (runAllPassiveEffectDestroysBeforeCreates) {
pendingPassiveHookEffectsUnmount.push(effect, fiber);
if (!rootDoesHavePassiveEffects) {
rootDoesHavePassiveEffects = true;
@@ -2224,7 +2224,7 @@ function flushPassiveEffectsImpl() {
executionContext |= CommitContext;
const prevInteractions = pushInteractions(root);
if (deferPassiveEffectCleanupDuringUnmount) {
if (runAllPassiveEffectDestroysBeforeCreates) {
// It's important that ALL pending passive effect destroy functions are called
// before ANY passive effect create functions are called.
// Otherwise effects in sibling components might interfere with each other.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+9
View File
@@ -91,10 +91,19 @@ export const enableTrustedTypesIntegration = false;
// Flag to turn event.target and event.currentTarget in ReactNative from a reactTag to a component instance
export const enableNativeTargetAsInstance = false;
// Controls sequence of passive effect destroy and create functions.
// If this flag is off, destroy and create functions may be interleaved.
// When the falg is on, all destroy functions will be run (for all fibers)
// before any create functions are run, similar to how layout effects work.
// This flag provides a killswitch if that proves to break existing code somehow.
export const runAllPassiveEffectDestroysBeforeCreates = false;
// Controls behavior of deferred effect destroy functions during unmount.
// Previously these functions were run during commit (along with layout effects).
// Ideally we should delay these until after commit for performance reasons.
// This flag provides a killswitch if that proves to break existing code somehow.
//
// WARNING This flag only has an affect if used with runAllPassiveEffectDestroysBeforeCreates.
export const deferPassiveEffectCleanupDuringUnmount = false;
export const isTestEnvironment = false;
@@ -53,6 +53,7 @@ export const disableUnstableRenderSubtreeIntoContainer = false;
export const warnUnstableRenderSubtreeIntoContainer = false;
export const disableUnstableCreatePortal = false;
export const deferPassiveEffectCleanupDuringUnmount = false;
export const runAllPassiveEffectDestroysBeforeCreates = false;
export const isTestEnvironment = false;
// Only used in www builds.
@@ -48,6 +48,7 @@ export const disableUnstableRenderSubtreeIntoContainer = false;
export const warnUnstableRenderSubtreeIntoContainer = false;
export const disableUnstableCreatePortal = false;
export const deferPassiveEffectCleanupDuringUnmount = false;
export const runAllPassiveEffectDestroysBeforeCreates = false;
export const isTestEnvironment = false;
// Only used in www builds.
@@ -48,6 +48,7 @@ export const disableUnstableRenderSubtreeIntoContainer = false;
export const warnUnstableRenderSubtreeIntoContainer = false;
export const disableUnstableCreatePortal = false;
export const deferPassiveEffectCleanupDuringUnmount = false;
export const runAllPassiveEffectDestroysBeforeCreates = false;
export const isTestEnvironment = false;
// Only used in www builds.
@@ -48,6 +48,7 @@ export const disableUnstableRenderSubtreeIntoContainer = false;
export const warnUnstableRenderSubtreeIntoContainer = false;
export const disableUnstableCreatePortal = false;
export const deferPassiveEffectCleanupDuringUnmount = false;
export const runAllPassiveEffectDestroysBeforeCreates = false;
export const isTestEnvironment = true; // this should probably *never* change
// Only used in www builds.
@@ -48,6 +48,7 @@ export const disableUnstableRenderSubtreeIntoContainer = false;
export const warnUnstableRenderSubtreeIntoContainer = false;
export const disableUnstableCreatePortal = false;
export const deferPassiveEffectCleanupDuringUnmount = false;
export const runAllPassiveEffectDestroysBeforeCreates = false;
export const isTestEnvironment = true; // this should probably *never* change
// Only used in www builds.
@@ -48,6 +48,7 @@ export const disableUnstableRenderSubtreeIntoContainer = false;
export const warnUnstableRenderSubtreeIntoContainer = false;
export const disableUnstableCreatePortal = false;
export const deferPassiveEffectCleanupDuringUnmount = false;
export const runAllPassiveEffectDestroysBeforeCreates = false;
export const isTestEnvironment = true;
// Only used in www builds.
@@ -13,9 +13,10 @@ import typeof * as ExportsType from './ReactFeatureFlags.www';
// Re-export dynamic flags from the www version.
export const {
debugRenderPhaseSideEffectsForStrictMode,
deferPassiveEffectCleanupDuringUnmount,
disableInputAttributeSyncing,
enableTrustedTypesIntegration,
deferPassiveEffectCleanupDuringUnmount,
runAllPassiveEffectDestroysBeforeCreates,
warnAboutShorthandPropertyCollision,
disableSchedulerTimeoutBasedOnReactExpirationTime,
} = require('ReactFeatureFlags');