@samitouri / QOS-React / commits / b789060dca

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.