@samitouri / QOS-React / commits / 1f5ce59dd7

[cleanup] fully roll out warnAboutSpreadingKeyToJSX (#26080)

I fully enabled this flag internally now and unless I see complications, we should be able to clean this up in the code.

Jan Kassens committed Jan 30, 2023 at 15:25 UTC 1f5ce59dd7b6869b1a17ede65aa301002ef31d4b
13 files changed +74 -106
packages/react/src/ReactElementValidator.js
+28 -33
@@ -21,7 +21,6 @@ import {
21 REACT_FRAGMENT_TYPE,
22 REACT_ELEMENT_TYPE,
23 } from 'shared/ReactSymbols';
24 -import {warnAboutSpreadingKeyToJSX} from 'shared/ReactFeatureFlags';
24 import checkPropTypes from 'shared/checkPropTypes';
25 import isArray from 'shared/isArray';
26
@@ -365,13 +364,11 @@ export function jsxWithValidation(
364 Object.freeze(children);
365 }
366 } else {
368 - if (__DEV__) {
369 - console.error(
370 - 'React.jsx: Static children should always be an array. ' +
371 - 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' +
372 - 'Use the Babel transform instead.',
373 - );
374 - }
367 + console.error(
368 + 'React.jsx: Static children should always be an array. ' +
369 + 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' +
370 + 'Use the Babel transform instead.',
371 + );
372 }
373 } else {
374 validateChildKeys(children, type);
@@ -379,31 +376,29 @@ export function jsxWithValidation(
376 }
377 }
378
382 - if (warnAboutSpreadingKeyToJSX) {
383 - if (hasOwnProperty.call(props, 'key')) {
384 - const componentName = getComponentNameFromType(type);
385 - const keys = Object.keys(props).filter(k => k !== 'key');
386 - const beforeExample =
387 - keys.length > 0
388 - ? '{key: someKey, ' + keys.join(': ..., ') + ': ...}'
389 - : '{key: someKey}';
390 - if (!didWarnAboutKeySpread[componentName + beforeExample]) {
391 - const afterExample =
392 - keys.length > 0 ? '{' + keys.join(': ..., ') + ': ...}' : '{}';
393 - console.error(
394 - 'A props object containing a "key" prop is being spread into JSX:\n' +
395 - ' let props = %s;\n' +
396 - ' <%s {...props} />\n' +
397 - 'React keys must be passed directly to JSX without using spread:\n' +
398 - ' let props = %s;\n' +
399 - ' <%s key={someKey} {...props} />',
400 - beforeExample,
401 - componentName,
402 - afterExample,
403 - componentName,
404 - );
405 - didWarnAboutKeySpread[componentName + beforeExample] = true;
406 - }
379 + if (hasOwnProperty.call(props, 'key')) {
380 + const componentName = getComponentNameFromType(type);
381 + const keys = Object.keys(props).filter(k => k !== 'key');
382 + const beforeExample =
383 + keys.length > 0
384 + ? '{key: someKey, ' + keys.join(': ..., ') + ': ...}'
385 + : '{key: someKey}';
386 + if (!didWarnAboutKeySpread[componentName + beforeExample]) {
387 + const afterExample =
388 + keys.length > 0 ? '{' + keys.join(': ..., ') + ': ...}' : '{}';
389 + console.error(
390 + 'A props object containing a "key" prop is being spread into JSX:\n' +
391 + ' let props = %s;\n' +
392 + ' <%s {...props} />\n' +
393 + 'React keys must be passed directly to JSX without using spread:\n' +
394 + ' let props = %s;\n' +
395 + ' <%s key={someKey} {...props} />',
396 + beforeExample,
397 + componentName,
398 + afterExample,
399 + componentName,
400 + );
401 + didWarnAboutKeySpread[componentName + beforeExample] = true;
402 }
403 }
404
packages/react/src/__tests__/ReactElementJSX-test.js
+23 -25
@@ -264,33 +264,31 @@ describe('ReactElement.jsx', () => {
264 );
265 });
266
267 - if (require('shared/ReactFeatureFlags').warnAboutSpreadingKeyToJSX) {
268 - it('should warn when keys are passed as part of props', () => {
269 - const container = document.createElement('div');
270 - class Child extends React.Component {
271 - render() {
272 - return JSXRuntime.jsx('div', {});
273 - }
267 + it('should warn when keys are passed as part of props', () => {
268 + const container = document.createElement('div');
269 + class Child extends React.Component {
270 + render() {
271 + return JSXRuntime.jsx('div', {});
272 }
275 - class Parent extends React.Component {
276 - render() {
277 - return JSXRuntime.jsx('div', {
278 - children: [JSXRuntime.jsx(Child, {key: '0', prop: 'hi'})],
279 - });
280 - }
273 + }
274 + class Parent extends React.Component {
275 + render() {
276 + return JSXRuntime.jsx('div', {
277 + children: [JSXRuntime.jsx(Child, {key: '0', prop: 'hi'})],
278 + });
279 }
282 - expect(() =>
283 - ReactDOM.render(JSXRuntime.jsx(Parent, {}), container),
284 - ).toErrorDev(
285 - 'Warning: A props object containing a "key" prop is being spread into JSX:\n' +
286 - ' let props = {key: someKey, prop: ...};\n' +
287 - ' <Child {...props} />\n' +
288 - 'React keys must be passed directly to JSX without using spread:\n' +
289 - ' let props = {prop: ...};\n' +
290 - ' <Child key={someKey} {...props} />',
291 - );
292 - });
293 - }
280 + }
281 + expect(() =>
282 + ReactDOM.render(JSXRuntime.jsx(Parent, {}), container),
283 + ).toErrorDev(
284 + 'Warning: A props object containing a "key" prop is being spread into JSX:\n' +
285 + ' let props = {key: someKey, prop: ...};\n' +
286 + ' <Child {...props} />\n' +
287 + 'React keys must be passed directly to JSX without using spread:\n' +
288 + ' let props = {prop: ...};\n' +
289 + ' <Child key={someKey} {...props} />',
290 + );
291 + });
292
293 it('should not warn when unkeyed children are passed to jsxs', () => {
294 const container = document.createElement('div');
packages/react/src/jsx/ReactJSXElementValidator.js
+23 -26
@@ -21,7 +21,6 @@ import {
21 REACT_FRAGMENT_TYPE,
22 REACT_ELEMENT_TYPE,
23 } from 'shared/ReactSymbols';
24 -import {warnAboutSpreadingKeyToJSX} from 'shared/ReactFeatureFlags';
24 import hasOwnProperty from 'shared/hasOwnProperty';
25 import isArray from 'shared/isArray';
26 import {jsxDEV} from './ReactJSXElement';
@@ -390,31 +389,29 @@ export function jsxWithValidation(
389 }
390 }
391
393 - if (warnAboutSpreadingKeyToJSX) {
394 - if (hasOwnProperty.call(props, 'key')) {
395 - const componentName = getComponentNameFromType(type);
396 - const keys = Object.keys(props).filter(k => k !== 'key');
397 - const beforeExample =
398 - keys.length > 0
399 - ? '{key: someKey, ' + keys.join(': ..., ') + ': ...}'
400 - : '{key: someKey}';
401 - if (!didWarnAboutKeySpread[componentName + beforeExample]) {
402 - const afterExample =
403 - keys.length > 0 ? '{' + keys.join(': ..., ') + ': ...}' : '{}';
404 - console.error(
405 - 'A props object containing a "key" prop is being spread into JSX:\n' +
406 - ' let props = %s;\n' +
407 - ' <%s {...props} />\n' +
408 - 'React keys must be passed directly to JSX without using spread:\n' +
409 - ' let props = %s;\n' +
410 - ' <%s key={someKey} {...props} />',
411 - beforeExample,
412 - componentName,
413 - afterExample,
414 - componentName,
415 - );
416 - didWarnAboutKeySpread[componentName + beforeExample] = true;
417 - }
392 + if (hasOwnProperty.call(props, 'key')) {
393 + const componentName = getComponentNameFromType(type);
394 + const keys = Object.keys(props).filter(k => k !== 'key');
395 + const beforeExample =
396 + keys.length > 0
397 + ? '{key: someKey, ' + keys.join(': ..., ') + ': ...}'
398 + : '{key: someKey}';
399 + if (!didWarnAboutKeySpread[componentName + beforeExample]) {
400 + const afterExample =
401 + keys.length > 0 ? '{' + keys.join(': ..., ') + ': ...}' : '{}';
402 + console.error(
403 + 'A props object containing a "key" prop is being spread into JSX:\n' +
404 + ' let props = %s;\n' +
405 + ' <%s {...props} />\n' +
406 + 'React keys must be passed directly to JSX without using spread:\n' +
407 + ' let props = %s;\n' +
408 + ' <%s key={someKey} {...props} />',
409 + beforeExample,
410 + componentName,
411 + afterExample,
412 + componentName,
413 + );
414 + didWarnAboutKeySpread[componentName + beforeExample] = true;
415 }
416 }
417
packages/shared/ReactFeatureFlags.js
-13
@@ -185,19 +185,6 @@ export const enableCustomElementPropertySupport = __EXPERIMENTAL__;
185 // Disables children for <textarea> elements
186 export const disableTextareaChildren = false;
187
188 -// -----------------------------------------------------------------------------
189 -// JSX Chopping Block
190 -//
191 -// Similar to main Chopping Block but only flags related to JSX. These are
192 -// grouped because we will likely batch all of them into a single major release.
193 -// -----------------------------------------------------------------------------
194 -
195 -// New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107
196 -
197 -// Enables a warning when trying to spread a 'key' to an element;
198 -// a deprecated pattern we want to get rid of in the future
199 -export const warnAboutSpreadingKeyToJSX = true;
200 -
188 // -----------------------------------------------------------------------------
189 // Debugging and DevTools
190 // -----------------------------------------------------------------------------
packages/shared/forks/ReactFeatureFlags.native-fb.js
-1
@@ -45,7 +45,6 @@ export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
45 export const enableTrustedTypesIntegration = false;
46 export const disableTextareaChildren = false;
47 export const disableModulePatternComponents = false;
48 -export const warnAboutSpreadingKeyToJSX = true;
48 export const enableSuspenseAvoidThisFallback = false;
49 export const enableSuspenseAvoidThisFallbackFizz = false;
50 export const enableCPUSuspense = true;
packages/shared/forks/ReactFeatureFlags.native-oss.js
-1
@@ -35,7 +35,6 @@ export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
35 export const enableTrustedTypesIntegration = false;
36 export const disableTextareaChildren = false;
37 export const disableModulePatternComponents = false;
38 -export const warnAboutSpreadingKeyToJSX = true;
38 export const enableSuspenseAvoidThisFallback = false;
39 export const enableSuspenseAvoidThisFallbackFizz = false;
40 export const enableCPUSuspense = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
-1
@@ -35,7 +35,6 @@ export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
35 export const enableTrustedTypesIntegration = false;
36 export const disableTextareaChildren = false;
37 export const disableModulePatternComponents = false;
38 -export const warnAboutSpreadingKeyToJSX = true;
38 export const enableSuspenseAvoidThisFallback = false;
39 export const enableSuspenseAvoidThisFallbackFizz = false;
40 export const enableCPUSuspense = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
-1
@@ -35,7 +35,6 @@ export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
35 export const enableTrustedTypesIntegration = false;
36 export const disableTextareaChildren = false;
37 export const disableModulePatternComponents = false;
38 -export const warnAboutSpreadingKeyToJSX = true;
38 export const enableComponentStackLocations = false;
39 export const enableLegacyFBSupport = false;
40 export const enableFilterEmptyStringAttributesDOM = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
-1
@@ -35,7 +35,6 @@ export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
35 export const enableTrustedTypesIntegration = false;
36 export const disableTextareaChildren = false;
37 export const disableModulePatternComponents = true;
38 -export const warnAboutSpreadingKeyToJSX = true;
38 export const enableSuspenseAvoidThisFallback = true;
39 export const enableSuspenseAvoidThisFallbackFizz = false;
40 export const enableCPUSuspense = false;
packages/shared/forks/ReactFeatureFlags.testing.js
-1
@@ -35,7 +35,6 @@ export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
35 export const enableTrustedTypesIntegration = false;
36 export const disableTextareaChildren = false;
37 export const disableModulePatternComponents = false;
38 -export const warnAboutSpreadingKeyToJSX = true;
38 export const enableSuspenseAvoidThisFallback = false;
39 export const enableSuspenseAvoidThisFallbackFizz = false;
40 export const enableCPUSuspense = false;
packages/shared/forks/ReactFeatureFlags.testing.www.js
-1
@@ -35,7 +35,6 @@ export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
35 export const enableTrustedTypesIntegration = false;
36 export const disableTextareaChildren = __EXPERIMENTAL__;
37 export const disableModulePatternComponents = true;
38 -export const warnAboutSpreadingKeyToJSX = true;
38 export const enableSuspenseAvoidThisFallback = true;
39 export const enableSuspenseAvoidThisFallbackFizz = false;
40 export const enableCPUSuspense = true;
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
-1
@@ -13,7 +13,6 @@
13 // Use __VARIANT__ to simulate a GK. The tests will be run twice: once
14 // with the __VARIANT__ set to `true`, and once set to `false`.
15
16 -export const warnAboutSpreadingKeyToJSX = __VARIANT__;
16 export const disableInputAttributeSyncing = __VARIANT__;
17 export const enableFilterEmptyStringAttributesDOM = __VARIANT__;
18 export const enableLegacyFBSupport = __VARIANT__;
packages/shared/forks/ReactFeatureFlags.www.js
-1
@@ -18,7 +18,6 @@ export const {
18 disableInputAttributeSyncing,
19 enableTrustedTypesIntegration,
20 disableSchedulerTimeoutBasedOnReactExpirationTime,
21 - warnAboutSpreadingKeyToJSX,
21 replayFailedUnitOfWorkWithInvokeGuardedCallback,
22 enableFilterEmptyStringAttributesDOM,
23 enableLegacyFBSupport,