Skip to content

Commit f0a5fac

Browse files
author
Brian Vaughn
committed
The exported '<React.StrictMode>' tag remains the same and opts legacy subtrees into strict mode level one ('mode == StrictModeL1'). This mode enables DEV-only double rendering, double component lifecycles, string ref warnings, legacy context warnings, etc. The primary purpose of this mode is to help detected render phase side effects. No new behavior. Roots created with experimental 'createRoot' and 'createBlockingRoot' APIs will also (for now) continue to default to strict mode level 1.
In a subsequent commit I will add support for a 'level' attribute on the '<React.StrictMode>' tag (as well as a new option supported by ). This will be the way to opt into strict mode level 2 ('mode == StrictModeL2'). This mode will enable DEV-only double invoking of effects on initial mount. This will simulate future Offscreen API semantics for trees being mounted, then hidden, and then shown again. The primary purpose of this mode is to enable applications to prepare for compatibility with the new Offscreen API (more information to follow shortly). For now, this commit changes no public facing behavior. The only mechanism for opting into strict mode level 2 is the pre-existing 'enableDoubleInvokingEffects' feature flag (only enabled within Facebook for now).
1 parent 8af27ae commit f0a5fac

22 files changed

+153
-121
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import {
4646
} from './ReactFiber.new';
4747
import {emptyRefsObject} from './ReactFiberClassComponent.new';
4848
import {isCompatibleFamilyForHotReloading} from './ReactFiberHotReloading.new';
49-
import {StrictMode} from './ReactTypeOfMode';
49+
import {StrictModeL1} from './ReactTypeOfMode';
5050

5151
let didWarnAboutMaps;
5252
let didWarnAboutGenerators;
@@ -114,7 +114,7 @@ function coerceRef(
114114
// TODO: Clean this up once we turn on the string ref warning for
115115
// everyone, because the strict mode case will no longer be relevant
116116
if (
117-
(returnFiber.mode & StrictMode || warnAboutStringRefs) &&
117+
(returnFiber.mode & StrictModeL1 || warnAboutStringRefs) &&
118118
// We warn in ReactElement.js if owner and self are equal for string refs
119119
// because these cannot be automatically converted to an arrow function
120120
// using a codemod. Therefore, we don't have to warn about string refs again.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import {
4646
} from './ReactFiber.old';
4747
import {emptyRefsObject} from './ReactFiberClassComponent.old';
4848
import {isCompatibleFamilyForHotReloading} from './ReactFiberHotReloading.old';
49-
import {StrictMode} from './ReactTypeOfMode';
49+
import {StrictModeL1} from './ReactTypeOfMode';
5050

5151
let didWarnAboutMaps;
5252
let didWarnAboutGenerators;
@@ -114,7 +114,7 @@ function coerceRef(
114114
// TODO: Clean this up once we turn on the string ref warning for
115115
// everyone, because the strict mode case will no longer be relevant
116116
if (
117-
(returnFiber.mode & StrictMode || warnAboutStringRefs) &&
117+
(returnFiber.mode & StrictModeL1 || warnAboutStringRefs) &&
118118
// We warn in ReactElement.js if owner and self are equal for string refs
119119
// because these cannot be automatically converted to an arrow function
120120
// using a codemod. Therefore, we don't have to warn about string refs again.

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

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ import type {OffscreenProps} from './ReactFiberOffscreenComponent';
1919

2020
import invariant from 'shared/invariant';
2121
import {
22+
enableCache,
23+
enableDoubleInvokingEffects,
2224
enableProfilerTimer,
2325
enableScopeAPI,
24-
enableCache,
2526
} from 'shared/ReactFeatureFlags';
2627
import {NoFlags, Placement, StaticMask} from './ReactFiberFlags';
2728
import {ConcurrentRoot, BlockingRoot} from './ReactRootTags';
@@ -64,7 +65,8 @@ import {
6465
ConcurrentMode,
6566
DebugTracingMode,
6667
ProfileMode,
67-
StrictMode,
68+
StrictModeL1,
69+
StrictModeL2,
6870
BlockingMode,
6971
} from './ReactTypeOfMode';
7072
import {
@@ -421,9 +423,17 @@ export function resetWorkInProgress(workInProgress: Fiber, renderLanes: Lanes) {
421423
export function createHostRootFiber(tag: RootTag): Fiber {
422424
let mode;
423425
if (tag === ConcurrentRoot) {
424-
mode = ConcurrentMode | BlockingMode | StrictMode;
426+
if (enableDoubleInvokingEffects) {
427+
mode = ConcurrentMode | BlockingMode | StrictModeL1 | StrictModeL2;
428+
} else {
429+
mode = ConcurrentMode | BlockingMode | StrictModeL1;
430+
}
425431
} else if (tag === BlockingRoot) {
426-
mode = BlockingMode | StrictMode;
432+
if (enableDoubleInvokingEffects) {
433+
mode = BlockingMode | StrictModeL1 | StrictModeL2;
434+
} else {
435+
mode = BlockingMode | StrictModeL1;
436+
}
427437
} else {
428438
mode = NoMode;
429439
}
@@ -472,7 +482,8 @@ export function createFiberFromTypeAndProps(
472482
break;
473483
case REACT_STRICT_MODE_TYPE:
474484
fiberTag = Mode;
475-
mode |= StrictMode;
485+
// TODO (StrictModeL2) Add support for new strict mode "level" attribute
486+
mode |= StrictModeL1;
476487
break;
477488
case REACT_PROFILER_TYPE:
478489
return createFiberFromProfiler(pendingProps, mode, lanes, key);

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

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ import type {OffscreenProps} from './ReactFiberOffscreenComponent';
1919

2020
import invariant from 'shared/invariant';
2121
import {
22+
enableCache,
23+
enableDoubleInvokingEffects,
2224
enableProfilerTimer,
2325
enableScopeAPI,
24-
enableCache,
2526
} from 'shared/ReactFeatureFlags';
2627
import {NoFlags, Placement, StaticMask} from './ReactFiberFlags';
2728
import {ConcurrentRoot, BlockingRoot} from './ReactRootTags';
@@ -64,7 +65,8 @@ import {
6465
ConcurrentMode,
6566
DebugTracingMode,
6667
ProfileMode,
67-
StrictMode,
68+
StrictModeL1,
69+
StrictModeL2,
6870
BlockingMode,
6971
} from './ReactTypeOfMode';
7072
import {
@@ -421,9 +423,17 @@ export function resetWorkInProgress(workInProgress: Fiber, renderLanes: Lanes) {
421423
export function createHostRootFiber(tag: RootTag): Fiber {
422424
let mode;
423425
if (tag === ConcurrentRoot) {
424-
mode = ConcurrentMode | BlockingMode | StrictMode;
426+
if (enableDoubleInvokingEffects) {
427+
mode = ConcurrentMode | BlockingMode | StrictModeL1 | StrictModeL2;
428+
} else {
429+
mode = ConcurrentMode | BlockingMode | StrictModeL1;
430+
}
425431
} else if (tag === BlockingRoot) {
426-
mode = BlockingMode | StrictMode;
432+
if (enableDoubleInvokingEffects) {
433+
mode = BlockingMode | StrictModeL1 | StrictModeL2;
434+
} else {
435+
mode = BlockingMode | StrictModeL1;
436+
}
427437
} else {
428438
mode = NoMode;
429439
}
@@ -472,7 +482,8 @@ export function createFiberFromTypeAndProps(
472482
break;
473483
case REACT_STRICT_MODE_TYPE:
474484
fiberTag = Mode;
475-
mode |= StrictMode;
485+
// TODO (StrictModeL2) Add support for new strict mode "level" attribute
486+
mode |= StrictModeL1;
476487
break;
477488
case REACT_PROFILER_TYPE:
478489
return createFiberFromProfiler(pendingProps, mode, lanes, key);

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ import {
125125
ConcurrentMode,
126126
NoMode,
127127
ProfileMode,
128-
StrictMode,
128+
StrictModeL1,
129129
BlockingMode,
130130
} from './ReactTypeOfMode';
131131
import {
@@ -357,7 +357,7 @@ function updateForwardRef(
357357
);
358358
if (
359359
debugRenderPhaseSideEffectsForStrictMode &&
360-
workInProgress.mode & StrictMode
360+
workInProgress.mode & StrictModeL1
361361
) {
362362
disableLogs();
363363
try {
@@ -889,7 +889,7 @@ function updateFunctionComponent(
889889
);
890890
if (
891891
debugRenderPhaseSideEffectsForStrictMode &&
892-
workInProgress.mode & StrictMode
892+
workInProgress.mode & StrictModeL1
893893
) {
894894
disableLogs();
895895
try {
@@ -1068,7 +1068,7 @@ function finishClassComponent(
10681068
nextChildren = instance.render();
10691069
if (
10701070
debugRenderPhaseSideEffectsForStrictMode &&
1071-
workInProgress.mode & StrictMode
1071+
workInProgress.mode & StrictModeL1
10721072
) {
10731073
disableLogs();
10741074
try {
@@ -1478,7 +1478,7 @@ function mountIndeterminateComponent(
14781478
}
14791479
}
14801480

1481-
if (workInProgress.mode & StrictMode) {
1481+
if (workInProgress.mode & StrictModeL1) {
14821482
ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
14831483
}
14841484

@@ -1615,7 +1615,7 @@ function mountIndeterminateComponent(
16151615

16161616
if (
16171617
debugRenderPhaseSideEffectsForStrictMode &&
1618-
workInProgress.mode & StrictMode
1618+
workInProgress.mode & StrictModeL1
16191619
) {
16201620
disableLogs();
16211621
try {

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ import {
125125
ConcurrentMode,
126126
NoMode,
127127
ProfileMode,
128-
StrictMode,
128+
StrictModeL1,
129129
BlockingMode,
130130
} from './ReactTypeOfMode';
131131
import {
@@ -357,7 +357,7 @@ function updateForwardRef(
357357
);
358358
if (
359359
debugRenderPhaseSideEffectsForStrictMode &&
360-
workInProgress.mode & StrictMode
360+
workInProgress.mode & StrictModeL1
361361
) {
362362
disableLogs();
363363
try {
@@ -889,7 +889,7 @@ function updateFunctionComponent(
889889
);
890890
if (
891891
debugRenderPhaseSideEffectsForStrictMode &&
892-
workInProgress.mode & StrictMode
892+
workInProgress.mode & StrictModeL1
893893
) {
894894
disableLogs();
895895
try {
@@ -1068,7 +1068,7 @@ function finishClassComponent(
10681068
nextChildren = instance.render();
10691069
if (
10701070
debugRenderPhaseSideEffectsForStrictMode &&
1071-
workInProgress.mode & StrictMode
1071+
workInProgress.mode & StrictModeL1
10721072
) {
10731073
disableLogs();
10741074
try {
@@ -1478,7 +1478,7 @@ function mountIndeterminateComponent(
14781478
}
14791479
}
14801480

1481-
if (workInProgress.mode & StrictMode) {
1481+
if (workInProgress.mode & StrictModeL1) {
14821482
ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
14831483
}
14841484

@@ -1615,7 +1615,7 @@ function mountIndeterminateComponent(
16151615

16161616
if (
16171617
debugRenderPhaseSideEffectsForStrictMode &&
1618-
workInProgress.mode & StrictMode
1618+
workInProgress.mode & StrictModeL1
16191619
) {
16201620
disableLogs();
16211621
try {

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

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,10 @@ import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols';
3131

3232
import {resolveDefaultProps} from './ReactFiberLazyComponent.new';
3333
import {
34-
BlockingMode,
35-
ConcurrentMode,
3634
DebugTracingMode,
3735
NoMode,
38-
StrictMode,
36+
StrictModeL1,
37+
StrictModeL2,
3938
} from './ReactTypeOfMode';
4039

4140
import {
@@ -165,7 +164,7 @@ export function applyDerivedStateFromProps(
165164
if (__DEV__) {
166165
if (
167166
debugRenderPhaseSideEffectsForStrictMode &&
168-
workInProgress.mode & StrictMode
167+
workInProgress.mode & StrictModeL1
169168
) {
170169
disableLogs();
171170
try {
@@ -318,7 +317,7 @@ function checkShouldComponentUpdate(
318317
if (__DEV__) {
319318
if (
320319
debugRenderPhaseSideEffectsForStrictMode &&
321-
workInProgress.mode & StrictMode
320+
workInProgress.mode & StrictModeL1
322321
) {
323322
disableLogs();
324323
try {
@@ -655,7 +654,7 @@ function constructClassInstance(
655654
if (__DEV__) {
656655
if (
657656
debugRenderPhaseSideEffectsForStrictMode &&
658-
workInProgress.mode & StrictMode
657+
workInProgress.mode & StrictModeL1
659658
) {
660659
disableLogs();
661660
try {
@@ -862,7 +861,7 @@ function mountClassInstance(
862861
}
863862
}
864863

865-
if (workInProgress.mode & StrictMode) {
864+
if (workInProgress.mode & StrictModeL1) {
866865
ReactStrictModeWarnings.recordLegacyContextWarning(
867866
workInProgress,
868867
instance,
@@ -910,7 +909,7 @@ function mountClassInstance(
910909
if (
911910
__DEV__ &&
912911
enableDoubleInvokingEffects &&
913-
(workInProgress.mode & (BlockingMode | ConcurrentMode)) !== NoMode
912+
(workInProgress.mode & StrictModeL2) !== NoMode
914913
) {
915914
// Never double-invoke effects for legacy roots.
916915
workInProgress.flags |= MountLayoutDev | Update;
@@ -989,7 +988,7 @@ function resumeMountClassInstance(
989988
if (
990989
__DEV__ &&
991990
enableDoubleInvokingEffects &&
992-
(workInProgress.mode & (BlockingMode | ConcurrentMode)) !== NoMode
991+
(workInProgress.mode & StrictModeL2) !== NoMode
993992
) {
994993
// Never double-invoke effects for legacy roots.
995994
workInProgress.flags |= MountLayoutDev | Update;
@@ -1041,7 +1040,7 @@ function resumeMountClassInstance(
10411040
if (
10421041
__DEV__ &&
10431042
enableDoubleInvokingEffects &&
1044-
(workInProgress.mode & (BlockingMode | ConcurrentMode)) !== NoMode
1043+
(workInProgress.mode & StrictModeL2) !== NoMode
10451044
) {
10461045
// Never double-invoke effects for legacy roots.
10471046
workInProgress.flags |= MountLayoutDev | Update;
@@ -1056,7 +1055,7 @@ function resumeMountClassInstance(
10561055
if (
10571056
__DEV__ &&
10581057
enableDoubleInvokingEffects &&
1059-
(workInProgress.mode & (BlockingMode | ConcurrentMode)) !== NoMode
1058+
(workInProgress.mode & StrictModeL2) !== NoMode
10601059
) {
10611060
// Never double-invoke effects for legacy roots.
10621061
workInProgress.flags |= MountLayoutDev | Update;

0 commit comments

Comments
 (0)