Warn if props obj passed into createElement / cloneElement inherits from anything other than Object
Richard committed
Feb 27, 2016 at 17:05 UTC
17683e041086d79665351437c4e1e31559fcc517
3 files changed
+40
src/isomorphic/classic/element/ReactElement.js
+16
@@ -127,6 +127,13 @@ ReactElement.createElement = function(type, config, children) {
127
128
if (config != null) {
129
if (__DEV__) {
130
+ warning(
131
+ /* eslint-disable no-proto */
132
+ config.__proto__ == null || config.__proto__ === Object.prototype,
133
+ /* eslint-enable no-proto */
134
+ 'React.createElement(...): Expected props argument to be a plain object. ' +
135
+ 'Properties defined in its prototype chain will be ignored.'
136
+ );
137
ref = !config.hasOwnProperty('ref') ||
138
Object.getOwnPropertyDescriptor(config, 'ref').get ? null : config.ref;
139
key = !config.hasOwnProperty('key') ||
@@ -269,6 +276,15 @@ ReactElement.cloneElement = function(element, config, children) {
276
var owner = element._owner;
277
278
if (config != null) {
279
+ if (__DEV__) {
280
+ warning(
281
+ /* eslint-disable no-proto */
282
+ config.__proto__ == null || config.__proto__ === Object.prototype,
283
+ /* eslint-enable no-proto */
284
+ 'React.cloneElement(...): Expected props argument to be a plain object. ' +
285
+ 'Properties defined in its prototype chain will be ignored.'
286
+ );
287
+ }
288
if (config.ref !== undefined) {
289
// Silently steal the ref from the parent.
290
ref = config.ref;
src/isomorphic/classic/element/__tests__/ReactElement-test.js
+12
@@ -139,6 +139,18 @@ describe('ReactElement', function() {
139
expect(element.props.foo).toBe(1);
140
});
141
142
+ it('warns if the config object inherits from any type other than Object', function() {
143
+ spyOn(console, 'error');
144
+ React.createElement('div', {foo: 1});
145
+ expect(console.error).not.toHaveBeenCalled();
146
+ React.createElement('div', Object.create({foo: 1}));
147
+ expect(console.error.argsForCall.length).toBe(1);
148
+ expect(console.error.argsForCall[0][0]).toContain(
149
+ 'React.createElement(...): Expected props argument to be a plain object. ' +
150
+ 'Properties defined in its prototype chain will be ignored.'
151
+ );
152
+ });
153
+
154
it('extracts key and ref from the config', function() {
155
var element = React.createFactory(ComponentClass)({
156
key: '12',
src/isomorphic/classic/element/__tests__/ReactElementClone-test.js
+12
@@ -66,6 +66,18 @@ describe('ReactElementClone', function() {
66
expect(ReactDOM.findDOMNode(component).childNodes[0].className).toBe('xyz');
67
});
68
69
+ it('should warn if the config object inherits from any type other than Object', function() {
70
+ spyOn(console, 'error');
71
+ React.cloneElement('div', {foo: 1});
72
+ expect(console.error).not.toHaveBeenCalled();
73
+ React.cloneElement('div', Object.create({foo: 1}));
74
+ expect(console.error.argsForCall.length).toBe(1);
75
+ expect(console.error.argsForCall[0][0]).toContain(
76
+ 'React.cloneElement(...): Expected props argument to be a plain object. ' +
77
+ 'Properties defined in its prototype chain will be ignored.'
78
+ );
79
+ });
80
+
81
it('should keep the original ref if it is not overridden', function() {
82
var Grandparent = React.createClass({
83
render: function() {