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.