314
* @param {string} key
315
*/
316
export function jsxProd(type, config, maybeKey) {
317
- let propName;
318
-
319
- // Reserved names are extracted
320
- const props = {};
321
-
317
let key = null;
318
let ref = null;
319
346
}
347
}
348
354
- // Remaining properties are added to a new props object
355
- for (propName in config) {
356
- if (
357
- hasOwnProperty.call(config, propName) &&
358
- // Skip over reserved prop names
359
- propName !== 'key' &&
360
- (enableRefAsProp || propName !== 'ref')
361
- ) {
362
- if (enableRefAsProp && !disableStringRefs && propName === 'ref') {
363
- props.ref = coerceStringRef(
364
- config[propName],
365
- ReactCurrentOwner.current,
366
- type,
367
- );
368
- } else {
369
- props[propName] = config[propName];
349
+ let props;
350
+ if (enableRefAsProp && disableStringRefs && !('key' in config)) {
351
+ // If key was not spread in, we can reuse the original props object. This
352
+ // only works for `jsx`, not `createElement`, because `jsx` is a compiler
353
+ // target and the compiler always passes a new object. For `createElement`,
354
+ // we can't assume a new object is passed every time because it can be
355
+ // called manually.
356
+ //
357
+ // Spreading key is a warning in dev. In a future release, we will not
358
+ // remove a spread key from the props object. (But we'll still warn.) We'll
359
+ // always pass the object straight through.
360
+ props = config;
361
+ } else {
362
+ // We need to remove reserved props (key, prop, ref). Create a fresh props
363
+ // object and copy over all the non-reserved props. We don't use `delete`
364
+ // because in V8 it will deopt the object to dictionary mode.
365
+ props = {};
366
+ for (const propName in config) {
367
+ if (
368
+ hasOwnProperty.call(config, propName) &&
369
+ // Skip over reserved prop names
370
+ propName !== 'key' &&
371
+ (enableRefAsProp || propName !== 'ref')
372
+ ) {
373
+ if (enableRefAsProp && !disableStringRefs && propName === 'ref') {
374
+ props.ref = coerceStringRef(
375
+ config[propName],
376
+ ReactCurrentOwner.current,
377
+ type,
378
+ );
379
+ } else {
380
+ props[propName] = config[propName];
381
+ }
382
}
383
}
384
}
387
// Resolve default props
388
if (type && type.defaultProps) {
389
const defaultProps = type.defaultProps;
378
- for (propName in defaultProps) {
390
+ for (const propName in defaultProps) {
391
if (props[propName] === undefined) {
392
props[propName] = defaultProps[propName];
393
}
550
}
551
}
552
541
- let propName;
542
-
543
- // Reserved names are extracted
544
- const props = {};
545
-
553
let key = null;
554
let ref = null;
555
585
}
586
}
587
581
- // Remaining properties are added to a new props object
582
- for (propName in config) {
583
- if (
584
- hasOwnProperty.call(config, propName) &&
585
- // Skip over reserved prop names
586
- propName !== 'key' &&
587
- (enableRefAsProp || propName !== 'ref')
588
- ) {
589
- if (enableRefAsProp && !disableStringRefs && propName === 'ref') {
590
- props.ref = coerceStringRef(
591
- config[propName],
592
- ReactCurrentOwner.current,
593
- type,
594
- );
595
- } else {
596
- props[propName] = config[propName];
588
+ let props;
589
+ if (enableRefAsProp && disableStringRefs && !('key' in config)) {
590
+ // If key was not spread in, we can reuse the original props object. This
591
+ // only works for `jsx`, not `createElement`, because `jsx` is a compiler
592
+ // target and the compiler always passes a new object. For `createElement`,
593
+ // we can't assume a new object is passed every time because it can be
594
+ // called manually.
595
+ //
596
+ // Spreading key is a warning in dev. In a future release, we will not
597
+ // remove a spread key from the props object. (But we'll still warn.) We'll
598
+ // always pass the object straight through.
599
+ props = config;
600
+ } else {
601
+ // We need to remove reserved props (key, prop, ref). Create a fresh props
602
+ // object and copy over all the non-reserved props. We don't use `delete`
603
+ // because in V8 it will deopt the object to dictionary mode.
604
+ props = {};
605
+ for (const propName in config) {
606
+ if (
607
+ hasOwnProperty.call(config, propName) &&
608
+ // Skip over reserved prop names
609
+ propName !== 'key' &&
610
+ (enableRefAsProp || propName !== 'ref')
611
+ ) {
612
+ if (enableRefAsProp && !disableStringRefs && propName === 'ref') {
613
+ props.ref = coerceStringRef(
614
+ config[propName],
615
+ ReactCurrentOwner.current,
616
+ type,
617
+ );
618
+ } else {
619
+ props[propName] = config[propName];
620
+ }
621
}
622
}
623
}
626
// Resolve default props
627
if (type && type.defaultProps) {
628
const defaultProps = type.defaultProps;
605
- for (propName in defaultProps) {
629
+ for (const propName in defaultProps) {
630
if (props[propName] === undefined) {
631
props[propName] = defaultProps[propName];
632
}