@samitouri / QOS-React-2 / commits / 750338ef47

Make ReactElement really a plain object

This should guarantee that the hidden class is the same after inlining.

Ben Alpert committed May 22, 2015 at 13:55 UTC 750338ef4794af164d452d7560cb97a558c56d3c
2 files changed +35 -23
src/isomorphic/classic/element/ReactElement.js
+32 -22
@@ -22,6 +22,16 @@ var RESERVED_PROPS = {
22 __source: true,
23 };
24
25 +var canDefineProperty = false;
26 +if (__DEV__) {
27 + try {
28 + Object.defineProperty({}, 'x', {});
29 + canDefineProperty = true;
30 + } catch (x) {
31 + // IE will fail on defineProperty
32 + }
33 +}
34 +
35 /**
36 * Base constructor for all React elements. This is only used to make this
37 * work with a dynamic instanceof check. Nothing should live on this prototype.
@@ -41,47 +51,47 @@ var RESERVED_PROPS = {
51 * @internal
52 */
53 var ReactElement = function(type, key, ref, self, source, owner, props) {
44 - // Built-in properties that belong on the element
45 - this.type = type;
46 - this.key = key;
47 - this.ref = ref;
48 - this.self = self;
49 - this.source = source;
54 + var element = {
55 + // Built-in properties that belong on the element
56 + type: type,
57 + key: key,
58 + ref: ref,
59 + self: self,
60 + source: source,
61
51 - // Record the component responsible for creating this element.
52 - this._owner = owner;
62 + // Record the component responsible for creating this element.
63 + _owner: owner,
64
54 - this.props = props;
65 + props: props,
66 + };
67
68 if (__DEV__) {
69 // The validation flag is currently mutative. We put it on
70 // an external backing store so that we can freeze the whole object.
71 // This can be replaced with a WeakMap once they are implemented in
72 // commonly used development environments.
61 - this._store = {};
73 + element._store = {};
74
75 // To make comparing ReactElements easier for testing purposes, we make
76 // the validation flag non-enumerable (where possible, which should
77 // include every environment we run tests in), so the test framework
78 // ignores it.
67 - try {
68 - Object.defineProperty(this._store, 'validated', {
79 + if (canDefineProperty) {
80 + Object.defineProperty(element._store, 'validated', {
81 configurable: false,
82 enumerable: false,
83 writable: true,
84 value: false,
85 });
74 - } catch (x) {
86 + } else {
87 this._store.validated = false;
88 }
77 - Object.freeze(this.props);
78 - Object.freeze(this);
89 + Object.freeze(element.props);
90 + Object.freeze(element);
91 }
80 -};
92
82 -// We intentionally don't expose the function on the constructor property.
83 -// ReactElement should be indistinguishable from a plain object.
84 -ReactElement.prototype = {};
93 + return element;
94 +};
95
96 ReactElement.createElement = function(type, config, children) {
97 var propName;
@@ -131,7 +141,7 @@ ReactElement.createElement = function(type, config, children) {
141 }
142 }
143
134 - return new ReactElement(
144 + return ReactElement(
145 type,
146 key,
147 ref,
@@ -168,7 +178,7 @@ ReactElement.cloneAndReplaceKey = function(oldElement, newKey) {
178 };
179
180 ReactElement.cloneAndReplaceProps = function(oldElement, newProps) {
171 - var newElement = new ReactElement(
181 + var newElement = ReactElement(
182 oldElement.type,
183 oldElement.key,
184 oldElement.ref,
@@ -232,7 +242,7 @@ ReactElement.cloneElement = function(element, config, children) {
242 props.children = childArray;
243 }
244
235 - return new ReactElement(
245 + return ReactElement(
246 element.type,
247 key,
248 ref,
src/isomorphic/classic/element/ReactElementValidator.js
+3 -1
@@ -144,7 +144,9 @@ function validateChildKeys(node, parentType) {
144 }
145 } else if (ReactElement.isValidElement(node)) {
146 // This element was passed in a valid location.
147 - node._store.validated = true;
147 + if (node._store) {
148 + node._store.validated = true;
149 + }
150 } else if (node) {
151 var iteratorFn = getIteratorFn(node);
152 // Entry iterators provide implicit keys.