Feature Flag for React.jsx` "spreading a key to jsx" warning (#18074)
Adds a feature flag for when React.jsx warns you about spreading a key into jsx. It's false for all builds, except as a dynamic flag for fb/www. I also included the component name in the warning.
Sunil Pai committed
Feb 20, 2020 at 11:30 UTC
b789060dca314f052d856cab509569cf41020cd5
11 files changed
+29
-8
packages/react/src/ReactElementValidator.js
+11
-7
@@ -21,6 +21,7 @@ import {
21
REACT_FRAGMENT_TYPE,
22
REACT_ELEMENT_TYPE,
23
} from 'shared/ReactSymbols';
24
+import {warnAboutSpreadingKeyToJSX} from 'shared/ReactFeatureFlags';
25
import checkPropTypes from 'prop-types/checkPropTypes';
26
27
import ReactCurrentOwner from './ReactCurrentOwner';
@@ -365,13 +366,16 @@ export function jsxWithValidation(
366
}
367
}
368
368
- if (hasOwnProperty.call(props, 'key')) {
369
- if (__DEV__) {
370
- console.error(
371
- 'React.jsx: Spreading a key to JSX is a deprecated pattern. ' +
372
- 'Explicitly pass a key after spreading props in your JSX call. ' +
373
- 'E.g. <ComponentName {...props} key={key} />',
374
- );
369
+ if (__DEV__) {
370
+ if (warnAboutSpreadingKeyToJSX) {
371
+ if (hasOwnProperty.call(props, 'key')) {
372
+ console.error(
373
+ 'React.jsx: Spreading a key to JSX is a deprecated pattern. ' +
374
+ 'Explicitly pass a key after spreading props in your JSX call. ' +
375
+ 'E.g. <%s {...props} key={key} />',
376
+ getComponentName(type) || 'ComponentName',
377
+ );
378
+ }
379
}
380
}
381
packages/react/src/__tests__/ReactElementJSX-test.internal.js
+2
-1
@@ -32,6 +32,7 @@ describe('ReactElement.jsx', () => {
32
33
ReactFeatureFlags = require('shared/ReactFeatureFlags');
34
ReactFeatureFlags.enableJSXTransformAPI = true;
35
+ ReactFeatureFlags.warnAboutSpreadingKeyToJSX = true;
36
37
React = require('react');
38
ReactDOM = require('react-dom');
@@ -371,7 +372,7 @@ describe('ReactElement.jsx', () => {
372
expect(() => ReactDOM.render(React.jsx(Parent, {}), container)).toErrorDev(
373
'Warning: React.jsx: Spreading a key to JSX is a deprecated pattern. ' +
374
'Explicitly pass a key after spreading props in your JSX call. ' +
374
- 'E.g. <ComponentName {...props} key={key} />',
375
+ 'E.g. <Child {...props} key={key} />',
376
);
377
});
378
packages/shared/ReactFeatureFlags.js
+8
@@ -48,6 +48,8 @@ export const disableJavaScriptURLs = false;
48
// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
49
export const exposeConcurrentModeAPIs = __EXPERIMENTAL__;
50
51
+// Warns when a combination of updates on a dom can cause a style declaration
52
+// that clashes with a previous one https://github.com/facebook/react/pull/14181
53
export const warnAboutShorthandPropertyCollision = true;
54
55
// Experimental React Flare event system and event components support.
@@ -106,8 +108,14 @@ export const runAllPassiveEffectDestroysBeforeCreates = false;
108
// WARNING This flag only has an affect if used with runAllPassiveEffectDestroysBeforeCreates.
109
export const deferPassiveEffectCleanupDuringUnmount = false;
110
111
+// Use this flag to generate "testing" builds, that include APIs like act()
112
+// and extra warnings/errors
113
export const isTestEnvironment = false;
114
115
+// Enables a warning when trying to spread a 'key' to an element;
116
+// a deprecated pattern we want to get rid of in the future
117
+export const warnAboutSpreadingKeyToJSX = false;
118
+
119
// --------------------------
120
// Future APIs to be deprecated
121
// --------------------------
packages/shared/forks/ReactFeatureFlags.native-fb.js
+1
@@ -56,6 +56,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
56
export const runAllPassiveEffectDestroysBeforeCreates = false;
57
export const isTestEnvironment = false;
58
export const enableModernEventSystem = false;
59
+export const warnAboutSpreadingKeyToJSX = false;
60
61
// Only used in www builds.
62
export function addUserTimingListener() {
packages/shared/forks/ReactFeatureFlags.native-oss.js
+1
@@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
51
export const runAllPassiveEffectDestroysBeforeCreates = false;
52
export const isTestEnvironment = false;
53
export const enableModernEventSystem = false;
54
+export const warnAboutSpreadingKeyToJSX = false;
55
56
// Only used in www builds.
57
export function addUserTimingListener() {
packages/shared/forks/ReactFeatureFlags.persistent.js
+1
@@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
51
export const runAllPassiveEffectDestroysBeforeCreates = false;
52
export const isTestEnvironment = false;
53
export const enableModernEventSystem = false;
54
+export const warnAboutSpreadingKeyToJSX = false;
55
56
// Only used in www builds.
57
export function addUserTimingListener() {
packages/shared/forks/ReactFeatureFlags.test-renderer.js
+1
@@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
51
export const runAllPassiveEffectDestroysBeforeCreates = false;
52
export const isTestEnvironment = true; // this should probably *never* change
53
export const enableModernEventSystem = false;
54
+export const warnAboutSpreadingKeyToJSX = false;
55
56
// Only used in www builds.
57
export function addUserTimingListener() {
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+1
@@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
51
export const runAllPassiveEffectDestroysBeforeCreates = false;
52
export const isTestEnvironment = true; // this should probably *never* change
53
export const enableModernEventSystem = false;
54
+export const warnAboutSpreadingKeyToJSX = false;
55
56
// Only used in www builds.
57
export function addUserTimingListener() {
packages/shared/forks/ReactFeatureFlags.testing.js
+1
@@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
51
export const runAllPassiveEffectDestroysBeforeCreates = false;
52
export const isTestEnvironment = true;
53
export const enableModernEventSystem = false;
54
+export const warnAboutSpreadingKeyToJSX = false;
55
56
// Only used in www builds.
57
export function addUserTimingListener() {
packages/shared/forks/ReactFeatureFlags.testing.www.js
+1
@@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
51
export const runAllPassiveEffectDestroysBeforeCreates = false;
52
export const isTestEnvironment = true;
53
export const enableModernEventSystem = false;
54
+export const warnAboutSpreadingKeyToJSX = false;
55
56
// Only used in www builds.
57
export function addUserTimingListener() {
packages/shared/forks/ReactFeatureFlags.www.js
+1
@@ -19,6 +19,7 @@ export const {
19
runAllPassiveEffectDestroysBeforeCreates,
20
warnAboutShorthandPropertyCollision,
21
disableSchedulerTimeoutBasedOnReactExpirationTime,
22
+ warnAboutSpreadingKeyToJSX,
23
} = require('ReactFeatureFlags');
24
25
// On WWW, __EXPERIMENTAL__ is used for a new modern build.