From b789060dca314f052d856cab509569cf41020cd5 Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Thu, 20 Feb 2020 11:30:04 +0000 Subject: [PATCH] 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. --- packages/react/src/ReactElementValidator.js | 18 +++++++++++------- .../__tests__/ReactElementJSX-test.internal.js | 3 ++- packages/shared/ReactFeatureFlags.js | 8 ++++++++ .../forks/ReactFeatureFlags.native-fb.js | 1 + .../forks/ReactFeatureFlags.native-oss.js | 1 + .../forks/ReactFeatureFlags.persistent.js | 1 + .../forks/ReactFeatureFlags.test-renderer.js | 1 + .../ReactFeatureFlags.test-renderer.www.js | 1 + .../shared/forks/ReactFeatureFlags.testing.js | 1 + .../forks/ReactFeatureFlags.testing.www.js | 1 + packages/shared/forks/ReactFeatureFlags.www.js | 1 + 11 files changed, 29 insertions(+), 8 deletions(-) diff --git a/packages/react/src/ReactElementValidator.js b/packages/react/src/ReactElementValidator.js index fa00f30d47d91..2fead4c017576 100644 --- a/packages/react/src/ReactElementValidator.js +++ b/packages/react/src/ReactElementValidator.js @@ -21,6 +21,7 @@ import { REACT_FRAGMENT_TYPE, REACT_ELEMENT_TYPE, } from 'shared/ReactSymbols'; +import {warnAboutSpreadingKeyToJSX} from 'shared/ReactFeatureFlags'; import checkPropTypes from 'prop-types/checkPropTypes'; import ReactCurrentOwner from './ReactCurrentOwner'; @@ -365,13 +366,16 @@ export function jsxWithValidation( } } - if (hasOwnProperty.call(props, 'key')) { - if (__DEV__) { - console.error( - 'React.jsx: Spreading a key to JSX is a deprecated pattern. ' + - 'Explicitly pass a key after spreading props in your JSX call. ' + - 'E.g. ', - ); + if (__DEV__) { + if (warnAboutSpreadingKeyToJSX) { + if (hasOwnProperty.call(props, 'key')) { + console.error( + 'React.jsx: Spreading a key to JSX is a deprecated pattern. ' + + 'Explicitly pass a key after spreading props in your JSX call. ' + + 'E.g. <%s {...props} key={key} />', + getComponentName(type) || 'ComponentName', + ); + } } } diff --git a/packages/react/src/__tests__/ReactElementJSX-test.internal.js b/packages/react/src/__tests__/ReactElementJSX-test.internal.js index fce448208c0dc..cb45ed714b78f 100644 --- a/packages/react/src/__tests__/ReactElementJSX-test.internal.js +++ b/packages/react/src/__tests__/ReactElementJSX-test.internal.js @@ -32,6 +32,7 @@ describe('ReactElement.jsx', () => { ReactFeatureFlags = require('shared/ReactFeatureFlags'); ReactFeatureFlags.enableJSXTransformAPI = true; + ReactFeatureFlags.warnAboutSpreadingKeyToJSX = true; React = require('react'); ReactDOM = require('react-dom'); @@ -371,7 +372,7 @@ describe('ReactElement.jsx', () => { expect(() => ReactDOM.render(React.jsx(Parent, {}), container)).toErrorDev( 'Warning: React.jsx: Spreading a key to JSX is a deprecated pattern. ' + 'Explicitly pass a key after spreading props in your JSX call. ' + - 'E.g. ', + 'E.g. ', ); }); diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index abe712ed685e4..383bbe3c248c0 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -48,6 +48,8 @@ export const disableJavaScriptURLs = false; // Control this behavior with a flag to support 16.6 minor releases in the meanwhile. export const exposeConcurrentModeAPIs = __EXPERIMENTAL__; +// Warns when a combination of updates on a dom can cause a style declaration +// that clashes with a previous one https://github.com/facebook/react/pull/14181 export const warnAboutShorthandPropertyCollision = true; // Experimental React Flare event system and event components support. @@ -106,8 +108,14 @@ export const runAllPassiveEffectDestroysBeforeCreates = false; // WARNING This flag only has an affect if used with runAllPassiveEffectDestroysBeforeCreates. export const deferPassiveEffectCleanupDuringUnmount = false; +// Use this flag to generate "testing" builds, that include APIs like act() +// and extra warnings/errors export const isTestEnvironment = false; +// Enables a warning when trying to spread a 'key' to an element; +// a deprecated pattern we want to get rid of in the future +export const warnAboutSpreadingKeyToJSX = false; + // -------------------------- // Future APIs to be deprecated // -------------------------- diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index ccbc3bc85f7fc..44fa3a158fd54 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -56,6 +56,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false; export const runAllPassiveEffectDestroysBeforeCreates = false; export const isTestEnvironment = false; export const enableModernEventSystem = false; +export const warnAboutSpreadingKeyToJSX = false; // Only used in www builds. export function addUserTimingListener() { diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index c1f2ad0d43dac..a637eb75d0c2f 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false; export const runAllPassiveEffectDestroysBeforeCreates = false; export const isTestEnvironment = false; export const enableModernEventSystem = false; +export const warnAboutSpreadingKeyToJSX = false; // Only used in www builds. export function addUserTimingListener() { diff --git a/packages/shared/forks/ReactFeatureFlags.persistent.js b/packages/shared/forks/ReactFeatureFlags.persistent.js index 3cd7a4c13b757..17a66058dc8da 100644 --- a/packages/shared/forks/ReactFeatureFlags.persistent.js +++ b/packages/shared/forks/ReactFeatureFlags.persistent.js @@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false; export const runAllPassiveEffectDestroysBeforeCreates = false; export const isTestEnvironment = false; export const enableModernEventSystem = false; +export const warnAboutSpreadingKeyToJSX = false; // Only used in www builds. export function addUserTimingListener() { diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 00176945bc98a..05375f1f04223 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false; export const runAllPassiveEffectDestroysBeforeCreates = false; export const isTestEnvironment = true; // this should probably *never* change export const enableModernEventSystem = false; +export const warnAboutSpreadingKeyToJSX = false; // Only used in www builds. export function addUserTimingListener() { diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 08b934bd589a2..423947d8b6eb9 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false; export const runAllPassiveEffectDestroysBeforeCreates = false; export const isTestEnvironment = true; // this should probably *never* change export const enableModernEventSystem = false; +export const warnAboutSpreadingKeyToJSX = false; // Only used in www builds. export function addUserTimingListener() { diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js index 4cf22fa4c42de..f19cecb601e02 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.js @@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false; export const runAllPassiveEffectDestroysBeforeCreates = false; export const isTestEnvironment = true; export const enableModernEventSystem = false; +export const warnAboutSpreadingKeyToJSX = false; // Only used in www builds. export function addUserTimingListener() { diff --git a/packages/shared/forks/ReactFeatureFlags.testing.www.js b/packages/shared/forks/ReactFeatureFlags.testing.www.js index db02d804dadc1..d82f90c473875 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.www.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.www.js @@ -51,6 +51,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false; export const runAllPassiveEffectDestroysBeforeCreates = false; export const isTestEnvironment = true; export const enableModernEventSystem = false; +export const warnAboutSpreadingKeyToJSX = false; // Only used in www builds. export function addUserTimingListener() { diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index ca181c34c0175..e9d2d9b3f306c 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -19,6 +19,7 @@ export const { runAllPassiveEffectDestroysBeforeCreates, warnAboutShorthandPropertyCollision, disableSchedulerTimeoutBasedOnReactExpirationTime, + warnAboutSpreadingKeyToJSX, } = require('ReactFeatureFlags'); // On WWW, __EXPERIMENTAL__ is used for a new modern build.