Skip to content

Commit abbbdf4

Browse files
authored
Put modern StrictMode behind a feature flag (#25365)
* Put modern StrictMode behind a feature flag * Remove unneeded flag
1 parent 4341103 commit abbbdf4

21 files changed

+637
-90
lines changed

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

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,20 @@ import type {UpdateQueue} from './ReactFiberClassUpdateQueue.new';
1313
import type {Flags} from './ReactFiberFlags';
1414

1515
import * as React from 'react';
16-
import {LayoutStatic, Update, Snapshot} from './ReactFiberFlags';
16+
import {
17+
LayoutStatic,
18+
Update,
19+
Snapshot,
20+
MountLayoutDev,
21+
} from './ReactFiberFlags';
1722
import {
1823
debugRenderPhaseSideEffectsForStrictMode,
1924
disableLegacyContext,
2025
enableDebugTracing,
2126
enableSchedulingProfiler,
2227
warnAboutDeprecatedLifecycles,
2328
enableLazyContextPropagation,
29+
enableStrictEffects,
2430
} from 'shared/ReactFeatureFlags';
2531
import ReactStrictModeWarnings from './ReactStrictModeWarnings.new';
2632
import {isMounted} from './ReactFiberTreeReflection';
@@ -33,7 +39,12 @@ import isArray from 'shared/isArray';
3339
import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols';
3440

3541
import {resolveDefaultProps} from './ReactFiberLazyComponent.new';
36-
import {DebugTracingMode, StrictLegacyMode} from './ReactTypeOfMode';
42+
import {
43+
DebugTracingMode,
44+
NoMode,
45+
StrictLegacyMode,
46+
StrictEffectsMode,
47+
} from './ReactTypeOfMode';
3748

3849
import {
3950
enqueueUpdate,
@@ -896,7 +907,14 @@ function mountClassInstance(
896907
}
897908

898909
if (typeof instance.componentDidMount === 'function') {
899-
const fiberFlags: Flags = Update | LayoutStatic;
910+
let fiberFlags: Flags = Update | LayoutStatic;
911+
if (
912+
__DEV__ &&
913+
enableStrictEffects &&
914+
(workInProgress.mode & StrictEffectsMode) !== NoMode
915+
) {
916+
fiberFlags |= MountLayoutDev;
917+
}
900918
workInProgress.flags |= fiberFlags;
901919
}
902920
}
@@ -967,7 +985,14 @@ function resumeMountClassInstance(
967985
// If an update was already in progress, we should schedule an Update
968986
// effect even though we're bailing out, so that cWU/cDU are called.
969987
if (typeof instance.componentDidMount === 'function') {
970-
const fiberFlags: Flags = Update | LayoutStatic;
988+
let fiberFlags: Flags = Update | LayoutStatic;
989+
if (
990+
__DEV__ &&
991+
enableStrictEffects &&
992+
(workInProgress.mode & StrictEffectsMode) !== NoMode
993+
) {
994+
fiberFlags |= MountLayoutDev;
995+
}
971996
workInProgress.flags |= fiberFlags;
972997
}
973998
return false;
@@ -1011,14 +1036,28 @@ function resumeMountClassInstance(
10111036
}
10121037
}
10131038
if (typeof instance.componentDidMount === 'function') {
1014-
const fiberFlags: Flags = Update | LayoutStatic;
1039+
let fiberFlags: Flags = Update | LayoutStatic;
1040+
if (
1041+
__DEV__ &&
1042+
enableStrictEffects &&
1043+
(workInProgress.mode & StrictEffectsMode) !== NoMode
1044+
) {
1045+
fiberFlags |= MountLayoutDev;
1046+
}
10151047
workInProgress.flags |= fiberFlags;
10161048
}
10171049
} else {
10181050
// If an update was already in progress, we should schedule an Update
10191051
// effect even though we're bailing out, so that cWU/cDU are called.
10201052
if (typeof instance.componentDidMount === 'function') {
1021-
const fiberFlags: Flags = Update | LayoutStatic;
1053+
let fiberFlags: Flags = Update | LayoutStatic;
1054+
if (
1055+
__DEV__ &&
1056+
enableStrictEffects &&
1057+
(workInProgress.mode & StrictEffectsMode) !== NoMode
1058+
) {
1059+
fiberFlags |= MountLayoutDev;
1060+
}
10221061
workInProgress.flags |= fiberFlags;
10231062
}
10241063

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

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,20 @@ import type {UpdateQueue} from './ReactFiberClassUpdateQueue.old';
1313
import type {Flags} from './ReactFiberFlags';
1414

1515
import * as React from 'react';
16-
import {LayoutStatic, Update, Snapshot} from './ReactFiberFlags';
16+
import {
17+
LayoutStatic,
18+
Update,
19+
Snapshot,
20+
MountLayoutDev,
21+
} from './ReactFiberFlags';
1722
import {
1823
debugRenderPhaseSideEffectsForStrictMode,
1924
disableLegacyContext,
2025
enableDebugTracing,
2126
enableSchedulingProfiler,
2227
warnAboutDeprecatedLifecycles,
2328
enableLazyContextPropagation,
29+
enableStrictEffects,
2430
} from 'shared/ReactFeatureFlags';
2531
import ReactStrictModeWarnings from './ReactStrictModeWarnings.old';
2632
import {isMounted} from './ReactFiberTreeReflection';
@@ -33,7 +39,12 @@ import isArray from 'shared/isArray';
3339
import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols';
3440

3541
import {resolveDefaultProps} from './ReactFiberLazyComponent.old';
36-
import {DebugTracingMode, StrictLegacyMode} from './ReactTypeOfMode';
42+
import {
43+
DebugTracingMode,
44+
NoMode,
45+
StrictLegacyMode,
46+
StrictEffectsMode,
47+
} from './ReactTypeOfMode';
3748

3849
import {
3950
enqueueUpdate,
@@ -896,7 +907,14 @@ function mountClassInstance(
896907
}
897908

898909
if (typeof instance.componentDidMount === 'function') {
899-
const fiberFlags: Flags = Update | LayoutStatic;
910+
let fiberFlags: Flags = Update | LayoutStatic;
911+
if (
912+
__DEV__ &&
913+
enableStrictEffects &&
914+
(workInProgress.mode & StrictEffectsMode) !== NoMode
915+
) {
916+
fiberFlags |= MountLayoutDev;
917+
}
900918
workInProgress.flags |= fiberFlags;
901919
}
902920
}
@@ -967,7 +985,14 @@ function resumeMountClassInstance(
967985
// If an update was already in progress, we should schedule an Update
968986
// effect even though we're bailing out, so that cWU/cDU are called.
969987
if (typeof instance.componentDidMount === 'function') {
970-
const fiberFlags: Flags = Update | LayoutStatic;
988+
let fiberFlags: Flags = Update | LayoutStatic;
989+
if (
990+
__DEV__ &&
991+
enableStrictEffects &&
992+
(workInProgress.mode & StrictEffectsMode) !== NoMode
993+
) {
994+
fiberFlags |= MountLayoutDev;
995+
}
971996
workInProgress.flags |= fiberFlags;
972997
}
973998
return false;
@@ -1011,14 +1036,28 @@ function resumeMountClassInstance(
10111036
}
10121037
}
10131038
if (typeof instance.componentDidMount === 'function') {
1014-
const fiberFlags: Flags = Update | LayoutStatic;
1039+
let fiberFlags: Flags = Update | LayoutStatic;
1040+
if (
1041+
__DEV__ &&
1042+
enableStrictEffects &&
1043+
(workInProgress.mode & StrictEffectsMode) !== NoMode
1044+
) {
1045+
fiberFlags |= MountLayoutDev;
1046+
}
10151047
workInProgress.flags |= fiberFlags;
10161048
}
10171049
} else {
10181050
// If an update was already in progress, we should schedule an Update
10191051
// effect even though we're bailing out, so that cWU/cDU are called.
10201052
if (typeof instance.componentDidMount === 'function') {
1021-
const fiberFlags: Flags = Update | LayoutStatic;
1053+
let fiberFlags: Flags = Update | LayoutStatic;
1054+
if (
1055+
__DEV__ &&
1056+
enableStrictEffects &&
1057+
(workInProgress.mode & StrictEffectsMode) !== NoMode
1058+
) {
1059+
fiberFlags |= MountLayoutDev;
1060+
}
10221061
workInProgress.flags |= fiberFlags;
10231062
}
10241063

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

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import {
5050
enableCache,
5151
enableTransitionTracing,
5252
enableUseEventHook,
53+
enableStrictEffects,
5354
} from 'shared/ReactFeatureFlags';
5455
import {
5556
FunctionComponent,
@@ -4109,4 +4110,111 @@ function commitPassiveUnmountInsideDeletedTreeOnFiber(
41094110
}
41104111
}
41114112

4112-
export {commitPlacement, commitAttachRef, commitDetachRef};
4113+
function invokeLayoutEffectMountInDEV(fiber: Fiber): void {
4114+
if (__DEV__ && enableStrictEffects) {
4115+
// We don't need to re-check StrictEffectsMode here.
4116+
// This function is only called if that check has already passed.
4117+
switch (fiber.tag) {
4118+
case FunctionComponent:
4119+
case ForwardRef:
4120+
case SimpleMemoComponent: {
4121+
try {
4122+
commitHookEffectListMount(HookLayout | HookHasEffect, fiber);
4123+
} catch (error) {
4124+
captureCommitPhaseError(fiber, fiber.return, error);
4125+
}
4126+
break;
4127+
}
4128+
case ClassComponent: {
4129+
const instance = fiber.stateNode;
4130+
try {
4131+
instance.componentDidMount();
4132+
} catch (error) {
4133+
captureCommitPhaseError(fiber, fiber.return, error);
4134+
}
4135+
break;
4136+
}
4137+
}
4138+
}
4139+
}
4140+
4141+
function invokePassiveEffectMountInDEV(fiber: Fiber): void {
4142+
if (__DEV__ && enableStrictEffects) {
4143+
// We don't need to re-check StrictEffectsMode here.
4144+
// This function is only called if that check has already passed.
4145+
switch (fiber.tag) {
4146+
case FunctionComponent:
4147+
case ForwardRef:
4148+
case SimpleMemoComponent: {
4149+
try {
4150+
commitHookEffectListMount(HookPassive | HookHasEffect, fiber);
4151+
} catch (error) {
4152+
captureCommitPhaseError(fiber, fiber.return, error);
4153+
}
4154+
break;
4155+
}
4156+
}
4157+
}
4158+
}
4159+
4160+
function invokeLayoutEffectUnmountInDEV(fiber: Fiber): void {
4161+
if (__DEV__ && enableStrictEffects) {
4162+
// We don't need to re-check StrictEffectsMode here.
4163+
// This function is only called if that check has already passed.
4164+
switch (fiber.tag) {
4165+
case FunctionComponent:
4166+
case ForwardRef:
4167+
case SimpleMemoComponent: {
4168+
try {
4169+
commitHookEffectListUnmount(
4170+
HookLayout | HookHasEffect,
4171+
fiber,
4172+
fiber.return,
4173+
);
4174+
} catch (error) {
4175+
captureCommitPhaseError(fiber, fiber.return, error);
4176+
}
4177+
break;
4178+
}
4179+
case ClassComponent: {
4180+
const instance = fiber.stateNode;
4181+
if (typeof instance.componentWillUnmount === 'function') {
4182+
safelyCallComponentWillUnmount(fiber, fiber.return, instance);
4183+
}
4184+
break;
4185+
}
4186+
}
4187+
}
4188+
}
4189+
4190+
function invokePassiveEffectUnmountInDEV(fiber: Fiber): void {
4191+
if (__DEV__ && enableStrictEffects) {
4192+
// We don't need to re-check StrictEffectsMode here.
4193+
// This function is only called if that check has already passed.
4194+
switch (fiber.tag) {
4195+
case FunctionComponent:
4196+
case ForwardRef:
4197+
case SimpleMemoComponent: {
4198+
try {
4199+
commitHookEffectListUnmount(
4200+
HookPassive | HookHasEffect,
4201+
fiber,
4202+
fiber.return,
4203+
);
4204+
} catch (error) {
4205+
captureCommitPhaseError(fiber, fiber.return, error);
4206+
}
4207+
}
4208+
}
4209+
}
4210+
}
4211+
4212+
export {
4213+
commitPlacement,
4214+
commitAttachRef,
4215+
commitDetachRef,
4216+
invokeLayoutEffectMountInDEV,
4217+
invokeLayoutEffectUnmountInDEV,
4218+
invokePassiveEffectMountInDEV,
4219+
invokePassiveEffectUnmountInDEV,
4220+
};

0 commit comments

Comments
 (0)