From 576ff6695f1566f933c92e1cbb98e686d14913c3 Mon Sep 17 00:00:00 2001 From: Zach Date: Mon, 21 Aug 2023 17:22:33 -0400 Subject: [PATCH] add react element changes --- packages/react/src/ReactElement.js | 41 +++++++++++++------ .../react/src/__tests__/ReactElement-test.js | 40 ++++++------------ 2 files changed, 40 insertions(+), 41 deletions(-) diff --git a/packages/react/src/ReactElement.js b/packages/react/src/ReactElement.js index e9d721b92693a..fd369ad80de55 100644 --- a/packages/react/src/ReactElement.js +++ b/packages/react/src/ReactElement.js @@ -192,11 +192,10 @@ function ReactElement(type, key, ref, self, source, owner, props) { writable: false, value: source, }); - if (Object.freeze) { - Object.freeze(element.props); - Object.freeze(element); - } + + Object.freeze(element); } + Object.freeze(element.props); return element; } @@ -363,17 +362,18 @@ export function createElement(type, config, children) { let propName; // Reserved names are extracted - const props = {}; + let props = {}; let key = null; let ref = null; let self = null; let source = null; + let allowPropsToReferenceConfig = true; + if (config != null) { if (hasValidRef(config)) { ref = config.ref; - if (__DEV__) { warnIfStringRefCannotBeAutoConverted(config); } @@ -387,13 +387,28 @@ export function createElement(type, config, children) { self = config.__self === undefined ? null : config.__self; source = config.__source === undefined ? null : config.__source; - // Remaining properties are added to a new props object - for (propName in config) { - if ( - hasOwnProperty.call(config, propName) && - !RESERVED_PROPS.hasOwnProperty(propName) - ) { - props[propName] = config[propName]; + + if ( + Object.isFrozen(config) || + hasOwnProperty.call(config, 'key') || + hasOwnProperty.call(config, 'ref') || + hasOwnProperty.call(config, '__self') || + hasOwnProperty.call(config, '__source') + ) { + allowPropsToReferenceConfig = false; + } + + if (allowPropsToReferenceConfig) { + props = config; + } else { + // Remaining properties are added to a new props object + for (propName in config) { + if ( + hasOwnProperty.call(config, propName) && + !RESERVED_PROPS.hasOwnProperty(propName) + ) { + props[propName] = config[propName]; + } } } } diff --git a/packages/react/src/__tests__/ReactElement-test.js b/packages/react/src/__tests__/ReactElement-test.js index a2440486c2867..ef5b22f27e244 100644 --- a/packages/react/src/__tests__/ReactElement-test.js +++ b/packages/react/src/__tests__/ReactElement-test.js @@ -129,7 +129,8 @@ describe('ReactElement', () => { const config = {foo: 1}; const element = React.createElement(ComponentClass, config); expect(element.props.foo).toBe(1); - config.foo = 2; + expect(() => (config.foo = 2)).toThrow(); + expect(element.props.foo).toBe(1); }); @@ -150,8 +151,9 @@ describe('ReactElement', () => { expect(element.ref).toBe('34'); if (__DEV__) { expect(Object.isFrozen(element)).toBe(true); - expect(Object.isFrozen(element.props)).toBe(true); } + expect(Object.isFrozen(element.props)).toBe(true); + expect(element.props).toEqual({foo: '56'}); }); @@ -333,25 +335,16 @@ describe('ReactElement', () => { render() { const el =
; - if (__DEV__) { - expect(function () { - el.props.className = 'quack'; - }).toThrow(); - expect(el.props.className).toBe('moo'); - } else { + expect(function () { el.props.className = 'quack'; - expect(el.props.className).toBe('quack'); - } + }).toThrow(); + expect(el.props.className).toBe('moo'); return el; } } const outer = ReactTestUtils.renderIntoDocument(); - if (__DEV__) { - expect(ReactDOM.findDOMNode(outer).className).toBe('moo'); - } else { - expect(ReactDOM.findDOMNode(outer).className).toBe('quack'); - } + expect(ReactDOM.findDOMNode(outer).className).toBe('moo'); }); it('throws when adding a prop (in dev) after element creation', () => { @@ -360,15 +353,10 @@ describe('ReactElement', () => { render() { const el =
{this.props.sound}
; - if (__DEV__) { - expect(function () { - el.props.className = 'quack'; - }).toThrow(); - expect(el.props.className).toBe(undefined); - } else { + expect(function () { el.props.className = 'quack'; - expect(el.props.className).toBe('quack'); - } + }).toThrow(); + expect(el.props.className).toBe(undefined); return el; } @@ -376,11 +364,7 @@ describe('ReactElement', () => { Outer.defaultProps = {sound: 'meow'}; const outer = ReactDOM.render(, container); expect(ReactDOM.findDOMNode(outer).textContent).toBe('meow'); - if (__DEV__) { - expect(ReactDOM.findDOMNode(outer).className).toBe(''); - } else { - expect(ReactDOM.findDOMNode(outer).className).toBe('quack'); - } + expect(ReactDOM.findDOMNode(outer).className).toBe(''); }); it('does not warn for NaN props', () => {