Make enableOwnerStacks dynamic (#31661)
following up on https://github.com/facebook/react/pull/31287, fixing tests --------- Co-authored-by: Rick Hanlon <rickhanlonii@fb.com>
Noah Lemen committed
Dec 11, 2024 at 12:00 UTC
a4964987dc140526702e996223fe7ee293def8ac
8 files changed
+92
-37
packages/react/index.fb.js
+10
@@ -7,6 +7,8 @@
7
* @flow
8
*/
9
10
+import {enableOwnerStacks} from 'shared/ReactFeatureFlags';
11
+import {captureOwnerStack as captureOwnerStackImpl} from './src/ReactClient';
12
export {
13
__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,
14
__COMPILER_RUNTIME,
@@ -68,3 +70,11 @@ export {useMemoCache as unstable_useMemoCache} from './src/ReactHooks';
70
// export to match the name of the OSS function typically exported from
71
// react/compiler-runtime
72
export {useMemoCache as c} from './src/ReactHooks';
73
+
74
+// Only export captureOwnerStack in development.
75
+let captureOwnerStack: ?() => null | string;
76
+if (__DEV__ && enableOwnerStacks) {
77
+ captureOwnerStack = captureOwnerStackImpl;
78
+}
79
+
80
+export {captureOwnerStack};
packages/react/src/ReactServer.fb.js
+9
@@ -10,6 +10,8 @@
10
export {default as __SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE} from './ReactSharedInternalsServer';
11
12
import {forEach, map, count, toArray, only} from './ReactChildren';
13
+import {enableOwnerStacks} from 'shared/ReactFeatureFlags';
14
+import {captureOwnerStack as captureOwnerStackImpl} from './ReactOwnerStack';
15
import {
16
REACT_FRAGMENT_TYPE,
17
REACT_PROFILER_TYPE,
@@ -37,6 +39,12 @@ const Children = {
39
only,
40
};
41
42
+// Only export captureOwnerStack if the flag is on, to support feature detection.
43
+let captureOwnerStack: ?() => null | string;
44
+if (__DEV__ && enableOwnerStacks) {
45
+ captureOwnerStack = captureOwnerStackImpl;
46
+}
47
+
48
export {
49
Children,
50
REACT_FRAGMENT_TYPE as Fragment,
@@ -57,4 +65,5 @@ export {
65
useDebugValue,
66
useMemo,
67
version,
68
+ captureOwnerStack, // DEV-only
69
};
packages/react/src/__tests__/ReactStrictMode-test.js
+61
-34
@@ -1028,40 +1028,67 @@ describe('context legacy', () => {
1028
root.render(<Root />);
1029
});
1030
1031
- assertConsoleErrorDev([
1032
- 'LegacyContextProvider uses the legacy childContextTypes API ' +
1033
- 'which will soon be removed. Use React.createContext() instead. ' +
1034
- '(https://react.dev/link/legacy-context)' +
1035
- '\n in LegacyContextProvider (at **)' +
1036
- '\n in div (at **)' +
1037
- '\n in Root (at **)',
1038
- 'LegacyContextConsumer uses the legacy contextTypes API which ' +
1039
- 'will soon be removed. Use React.createContext() with static ' +
1040
- 'contextType instead. (https://react.dev/link/legacy-context)' +
1041
- '\n in LegacyContextConsumer (at **)' +
1042
- '\n in div (at **)' +
1043
- '\n in LegacyContextProvider (at **)' +
1044
- '\n in div (at **)' +
1045
- '\n in Root (at **)',
1046
- 'FunctionalLegacyContextConsumer uses the legacy contextTypes ' +
1047
- 'API which will be removed soon. Use React.createContext() ' +
1048
- 'with React.useContext() instead. (https://react.dev/link/legacy-context)' +
1049
- '\n in FunctionalLegacyContextConsumer (at **)' +
1050
- '\n in div (at **)' +
1051
- '\n in LegacyContextProvider (at **)' +
1052
- '\n in div (at **)' +
1053
- '\n in Root (at **)',
1054
- 'Legacy context API has been detected within a strict-mode tree.' +
1055
- '\n\nThe old API will be supported in all 16.x releases, but applications ' +
1056
- 'using it should migrate to the new version.' +
1057
- '\n\nPlease update the following components: ' +
1058
- 'FunctionalLegacyContextConsumer, LegacyContextConsumer, LegacyContextProvider' +
1059
- '\n\nLearn more about this warning here: ' +
1060
- 'https://react.dev/link/legacy-context' +
1061
- '\n in LegacyContextProvider (at **)' +
1062
- '\n in div (at **)' +
1063
- '\n in Root (at **)',
1064
- ]);
1031
+ if (gate(flags => flags.enableOwnerStacks)) {
1032
+ assertConsoleErrorDev([
1033
+ 'LegacyContextProvider uses the legacy childContextTypes API ' +
1034
+ 'which will soon be removed. Use React.createContext() instead. ' +
1035
+ '(https://react.dev/link/legacy-context)' +
1036
+ '\n in Root (at **)',
1037
+ 'LegacyContextConsumer uses the legacy contextTypes API which ' +
1038
+ 'will soon be removed. Use React.createContext() with static ' +
1039
+ 'contextType instead. (https://react.dev/link/legacy-context)' +
1040
+ '\n in LegacyContextProvider (at **)' +
1041
+ '\n in Root (at **)',
1042
+ 'FunctionalLegacyContextConsumer uses the legacy contextTypes ' +
1043
+ 'API which will be removed soon. Use React.createContext() ' +
1044
+ 'with React.useContext() instead. (https://react.dev/link/legacy-context)' +
1045
+ '\n in LegacyContextProvider (at **)' +
1046
+ '\n in Root (at **)',
1047
+ 'Legacy context API has been detected within a strict-mode tree.' +
1048
+ '\n\nThe old API will be supported in all 16.x releases, but applications ' +
1049
+ 'using it should migrate to the new version.' +
1050
+ '\n\nPlease update the following components: ' +
1051
+ 'FunctionalLegacyContextConsumer, LegacyContextConsumer, LegacyContextProvider' +
1052
+ '\n\nLearn more about this warning here: ' +
1053
+ 'https://react.dev/link/legacy-context' +
1054
+ '\n in Root (at **)',
1055
+ ]);
1056
+ } else {
1057
+ assertConsoleErrorDev([
1058
+ 'LegacyContextProvider uses the legacy childContextTypes API ' +
1059
+ 'which will soon be removed. Use React.createContext() instead. ' +
1060
+ '(https://react.dev/link/legacy-context)' +
1061
+ '\n in LegacyContextProvider (at **)' +
1062
+ '\n in div (at **)' +
1063
+ '\n in Root (at **)',
1064
+ 'LegacyContextConsumer uses the legacy contextTypes API which ' +
1065
+ 'will soon be removed. Use React.createContext() with static ' +
1066
+ 'contextType instead. (https://react.dev/link/legacy-context)' +
1067
+ '\n in LegacyContextConsumer (at **)' +
1068
+ '\n in div (at **)' +
1069
+ '\n in LegacyContextProvider (at **)' +
1070
+ '\n in div (at **)' +
1071
+ '\n in Root (at **)',
1072
+ 'FunctionalLegacyContextConsumer uses the legacy contextTypes ' +
1073
+ 'API which will be removed soon. Use React.createContext() ' +
1074
+ 'with React.useContext() instead. (https://react.dev/link/legacy-context)' +
1075
+ '\n in FunctionalLegacyContextConsumer (at **)' +
1076
+ '\n in div (at **)' +
1077
+ '\n in LegacyContextProvider (at **)' +
1078
+ '\n in div (at **)' +
1079
+ '\n in Root (at **)',
1080
+ 'Legacy context API has been detected within a strict-mode tree.' +
1081
+ '\n\nThe old API will be supported in all 16.x releases, but applications ' +
1082
+ 'using it should migrate to the new version.' +
1083
+ '\n\nPlease update the following components: ' +
1084
+ 'FunctionalLegacyContextConsumer, LegacyContextConsumer, LegacyContextProvider' +
1085
+ '\n\nLearn more about this warning here: ' +
1086
+ 'https://react.dev/link/legacy-context' +
1087
+ '\n in LegacyContextProvider (at **)' +
1088
+ '\n in div (at **)' +
1089
+ '\n in Root (at **)',
1090
+ ]);
1091
+ }
1092
1093
// Dedupe
1094
await act(() => {
packages/react/src/__tests__/createReactClassIntegration-test.js
+8
-1
@@ -338,7 +338,14 @@ describe('create-react-class-integration', () => {
338
root.render(<Outer />);
339
});
340
assertConsoleErrorDev([
341
- 'Component uses the legacy childContextTypes API which will soon be removed. Use React.createContext() instead.',
341
+ gate(flags =>
342
+ flags.enableOwnerStacks
343
+ ? [
344
+ 'Component uses the legacy childContextTypes API which will soon be removed. Use React.createContext() instead.',
345
+ {withoutStack: true},
346
+ ]
347
+ : 'Component uses the legacy childContextTypes API which will soon be removed. Use React.createContext() instead.',
348
+ ),
349
'Component uses the legacy contextTypes API which will soon be removed. Use React.createContext() with static contextType instead.',
350
]);
351
expect(container.firstChild.className).toBe('foo');
packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js
+1
@@ -26,3 +26,4 @@ export const passChildrenWhenCloningPersistedNodes = __VARIANT__;
26
export const enableFabricCompleteRootInCommitPhase = __VARIANT__;
27
export const enableSiblingPrerendering = __VARIANT__;
28
export const enableUseResourceEffectHook = __VARIANT__;
29
+export const enableOwnerStacks = __VARIANT__;
packages/shared/forks/ReactFeatureFlags.native-fb.js
+1
-1
@@ -28,6 +28,7 @@ export const {
28
enableUseResourceEffectHook,
29
passChildrenWhenCloningPersistedNodes,
30
enableSiblingPrerendering,
31
+ enableOwnerStacks,
32
} = dynamicFlags;
33
34
// The rest of the flags are static for better dead code elimination.
@@ -67,7 +68,6 @@ export const enableLegacyCache = false;
68
export const enableLegacyFBSupport = false;
69
export const enableLegacyHidden = false;
70
export const enableNoCloningMemoCache = false;
70
-export const enableOwnerStacks = false;
71
export const enablePostpone = false;
72
export const enableProfilerCommitHooks = __PROFILE__;
73
export const enableProfilerNestedUpdatePhase = __PROFILE__;
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
+1
@@ -27,6 +27,7 @@ export const enableRetryLaneExpiration = __VARIANT__;
27
export const enableTransitionTracing = __VARIANT__;
28
export const favorSafetyOverHydrationPerf = __VARIANT__;
29
export const renameElementSymbol = __VARIANT__;
30
+export const enableOwnerStacks = __VARIANT__;
31
export const retryLaneExpirationMs = 5000;
32
export const syncLaneExpirationMs = 250;
33
export const transitionLaneExpirationMs = 5000;
packages/shared/forks/ReactFeatureFlags.www.js
+1
-1
@@ -37,6 +37,7 @@ export const {
37
retryLaneExpirationMs,
38
syncLaneExpirationMs,
39
transitionLaneExpirationMs,
40
+ enableOwnerStacks,
41
} = dynamicFeatureFlags;
42
43
// On WWW, __EXPERIMENTAL__ is used for a new modern build.
@@ -121,7 +122,6 @@ export const useModernStrictMode = true;
122
123
export const disableLegacyMode = true;
124
124
-export const enableOwnerStacks = false;
125
export const enableShallowPropDiffing = false;
126
127
// Flow magic to verify the exports of this file match the original version.