From 2e4e662cb72d68ae417fa297c82548c40ed1007c Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Tue, 6 Feb 2024 18:56:18 -0500 Subject: [PATCH] jsx(): Inline reserved prop checks (#28262) The JSX runtime (both the new one and the classic createElement runtime) check for reserved props like `key` and `ref` by doing a lookup in a plain object map with `hasOwnProperty`. There are only a few reserved props so this inlines the checks instead. --- packages/react/src/ReactElementProd.js | 21 ++++++++++++--------- packages/react/src/jsx/ReactJSXElement.js | 21 ++++++++++++--------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/packages/react/src/ReactElementProd.js b/packages/react/src/ReactElementProd.js index cfb0758afa7e2..88b87a6dfb651 100644 --- a/packages/react/src/ReactElementProd.js +++ b/packages/react/src/ReactElementProd.js @@ -13,13 +13,6 @@ import {checkKeyStringCoercion} from 'shared/CheckStringCoercion'; import ReactCurrentOwner from './ReactCurrentOwner'; -const RESERVED_PROPS = { - key: true, - ref: true, - __self: true, - __source: true, -}; - let specialPropKeyWarningShown, specialPropRefWarningShown, didWarnAboutStringRefs; @@ -237,7 +230,12 @@ export function createElement(type, config, children) { for (propName in config) { if ( hasOwnProperty.call(config, propName) && - !RESERVED_PROPS.hasOwnProperty(propName) + // Skip over reserved prop names + propName !== 'key' && + // TODO: These will no longer be reserved in the next major + propName !== 'ref' && + propName !== '__self' && + propName !== '__source' ) { props[propName] = config[propName]; } @@ -375,7 +373,12 @@ export function cloneElement(element, config, children) { for (propName in config) { if ( hasOwnProperty.call(config, propName) && - !RESERVED_PROPS.hasOwnProperty(propName) + // Skip over reserved prop names + propName !== 'key' && + // TODO: These will no longer be reserved in the next major + propName !== 'ref' && + propName !== '__self' && + propName !== '__source' ) { if (config[propName] === undefined && defaultProps !== undefined) { // Resolve default props diff --git a/packages/react/src/jsx/ReactJSXElement.js b/packages/react/src/jsx/ReactJSXElement.js index e2d8fe0af4aeb..849d2e1604db0 100644 --- a/packages/react/src/jsx/ReactJSXElement.js +++ b/packages/react/src/jsx/ReactJSXElement.js @@ -13,13 +13,6 @@ import {checkKeyStringCoercion} from 'shared/CheckStringCoercion'; const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; -const RESERVED_PROPS = { - key: true, - ref: true, - __self: true, - __source: true, -}; - let specialPropKeyWarningShown; let specialPropRefWarningShown; let didWarnAboutStringRefs; @@ -244,7 +237,12 @@ export function jsx(type, config, maybeKey) { for (propName in config) { if ( hasOwnProperty.call(config, propName) && - !RESERVED_PROPS.hasOwnProperty(propName) + // Skip over reserved prop names + propName !== 'key' && + // TODO: These will no longer be reserved in the next major + propName !== 'ref' && + propName !== '__self' && + propName !== '__source' ) { props[propName] = config[propName]; } @@ -316,7 +314,12 @@ export function jsxDEV(type, config, maybeKey, source, self) { for (propName in config) { if ( hasOwnProperty.call(config, propName) && - !RESERVED_PROPS.hasOwnProperty(propName) + // Skip over reserved prop names + propName !== 'key' && + // TODO: These will no longer be reserved in the next major + propName !== 'ref' && + propName !== '__self' && + propName !== '__source' ) { props[propName] = config[propName]; }