Skip to content

Commit b789060

Browse files
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.
1 parent 3f85d53 commit b789060

11 files changed

+29
-8
lines changed

packages/react/src/ReactElementValidator.js

+11-7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
REACT_FRAGMENT_TYPE,
2222
REACT_ELEMENT_TYPE,
2323
} from 'shared/ReactSymbols';
24+
import {warnAboutSpreadingKeyToJSX} from 'shared/ReactFeatureFlags';
2425
import checkPropTypes from 'prop-types/checkPropTypes';
2526

2627
import ReactCurrentOwner from './ReactCurrentOwner';
@@ -365,13 +366,16 @@ export function jsxWithValidation(
365366
}
366367
}
367368

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+
}
375379
}
376380
}
377381

packages/react/src/__tests__/ReactElementJSX-test.internal.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ describe('ReactElement.jsx', () => {
3232

3333
ReactFeatureFlags = require('shared/ReactFeatureFlags');
3434
ReactFeatureFlags.enableJSXTransformAPI = true;
35+
ReactFeatureFlags.warnAboutSpreadingKeyToJSX = true;
3536

3637
React = require('react');
3738
ReactDOM = require('react-dom');
@@ -371,7 +372,7 @@ describe('ReactElement.jsx', () => {
371372
expect(() => ReactDOM.render(React.jsx(Parent, {}), container)).toErrorDev(
372373
'Warning: React.jsx: Spreading a key to JSX is a deprecated pattern. ' +
373374
'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} />',
375376
);
376377
});
377378

packages/shared/ReactFeatureFlags.js

+8
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ export const disableJavaScriptURLs = false;
4848
// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
4949
export const exposeConcurrentModeAPIs = __EXPERIMENTAL__;
5050

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
5153
export const warnAboutShorthandPropertyCollision = true;
5254

5355
// Experimental React Flare event system and event components support.
@@ -106,8 +108,14 @@ export const runAllPassiveEffectDestroysBeforeCreates = false;
106108
// WARNING This flag only has an affect if used with runAllPassiveEffectDestroysBeforeCreates.
107109
export const deferPassiveEffectCleanupDuringUnmount = false;
108110

111+
// Use this flag to generate "testing" builds, that include APIs like act()
112+
// and extra warnings/errors
109113
export const isTestEnvironment = false;
110114

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+
111119
// --------------------------
112120
// Future APIs to be deprecated
113121
// --------------------------

packages/shared/forks/ReactFeatureFlags.native-fb.js

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
5656
export const runAllPassiveEffectDestroysBeforeCreates = false;
5757
export const isTestEnvironment = false;
5858
export const enableModernEventSystem = false;
59+
export const warnAboutSpreadingKeyToJSX = false;
5960

6061
// Only used in www builds.
6162
export function addUserTimingListener() {

packages/shared/forks/ReactFeatureFlags.native-oss.js

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
5151
export const runAllPassiveEffectDestroysBeforeCreates = false;
5252
export const isTestEnvironment = false;
5353
export const enableModernEventSystem = false;
54+
export const warnAboutSpreadingKeyToJSX = false;
5455

5556
// Only used in www builds.
5657
export function addUserTimingListener() {

packages/shared/forks/ReactFeatureFlags.persistent.js

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
5151
export const runAllPassiveEffectDestroysBeforeCreates = false;
5252
export const isTestEnvironment = false;
5353
export const enableModernEventSystem = false;
54+
export const warnAboutSpreadingKeyToJSX = false;
5455

5556
// Only used in www builds.
5657
export function addUserTimingListener() {

packages/shared/forks/ReactFeatureFlags.test-renderer.js

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
5151
export const runAllPassiveEffectDestroysBeforeCreates = false;
5252
export const isTestEnvironment = true; // this should probably *never* change
5353
export const enableModernEventSystem = false;
54+
export const warnAboutSpreadingKeyToJSX = false;
5455

5556
// Only used in www builds.
5657
export function addUserTimingListener() {

packages/shared/forks/ReactFeatureFlags.test-renderer.www.js

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
5151
export const runAllPassiveEffectDestroysBeforeCreates = false;
5252
export const isTestEnvironment = true; // this should probably *never* change
5353
export const enableModernEventSystem = false;
54+
export const warnAboutSpreadingKeyToJSX = false;
5455

5556
// Only used in www builds.
5657
export function addUserTimingListener() {

packages/shared/forks/ReactFeatureFlags.testing.js

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
5151
export const runAllPassiveEffectDestroysBeforeCreates = false;
5252
export const isTestEnvironment = true;
5353
export const enableModernEventSystem = false;
54+
export const warnAboutSpreadingKeyToJSX = false;
5455

5556
// Only used in www builds.
5657
export function addUserTimingListener() {

packages/shared/forks/ReactFeatureFlags.testing.www.js

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
5151
export const runAllPassiveEffectDestroysBeforeCreates = false;
5252
export const isTestEnvironment = true;
5353
export const enableModernEventSystem = false;
54+
export const warnAboutSpreadingKeyToJSX = false;
5455

5556
// Only used in www builds.
5657
export function addUserTimingListener() {

packages/shared/forks/ReactFeatureFlags.www.js

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const {
1919
runAllPassiveEffectDestroysBeforeCreates,
2020
warnAboutShorthandPropertyCollision,
2121
disableSchedulerTimeoutBasedOnReactExpirationTime,
22+
warnAboutSpreadingKeyToJSX,
2223
} = require('ReactFeatureFlags');
2324

2425
// On WWW, __EXPERIMENTAL__ is used for a new modern build.

0 commit comments

Comments
 (0)