@samitouri / QOS-React / commits / 17683e0410

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() {