Skip to content

Commit

Permalink
Warns when mutated props are passed.
Browse files Browse the repository at this point in the history
  • Loading branch information
ManasJayanth committed Nov 4, 2015
1 parent 7619214 commit b05ffdd
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/renderers/shared/reconciler/ReactCompositeComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var emptyObject = require('emptyObject');
var invariant = require('invariant');
var shouldUpdateReactComponent = require('shouldUpdateReactComponent');
var warning = require('warning');
var shallowEqual = require('shallowEqual');

function getDeclarationErrorAddendum(component) {
var owner = component._currentElement._owner || null;
Expand Down Expand Up @@ -147,6 +148,7 @@ var ReactCompositeComponentMixin = {
// Initialize the public class
var inst;
var renderedElement;
var propsMutated;

// This is a way to detect if Component is a stateless arrow function
// component, which is not newable. It might not be 100% reliable but is
Expand Down Expand Up @@ -195,6 +197,17 @@ var ReactCompositeComponentMixin = {
Component.displayName || Component.name || 'Component'
);
}

propsMutated = !shallowEqual(inst.props, publicProps);
if (propsMutated) {
warning(
!propsMutated,
'Constructor (of %s) may not invoke super(...) with props that ' +
'differ from the props that were initially passed in from the' +
' component\'s owner.',
Component.displayName || Component.name || 'Component'
);
}
}

// These should be set up in the constructor, but as a convenience for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1241,4 +1241,51 @@ describe('ReactCompositeComponent', function() {

});

it('should warn when mutated props are passed', function() {

var container = document.createElement('div');

function Foo (props) {
React.Component.call(this, props);
}

Foo.prototype = Object.create(React.Component.prototype, {
constructor: {
value: Foo,
},
});

Foo.prototype.render = function() {
return <span />;
};

function Bar (props) {
var _props = { idx: props.idx + '?' };

Foo.call(this, _props);
}

Bar.prototype = Object.create(Foo.prototype, {
constructor: {
value: Bar,
},
});

Bar.prototype.render = function() {
return <span />;
};

expect(console.error.calls.length).toBe(0);

ReactDOM.render(<Bar idx="qwe" />, container);

expect(console.error.calls.length).toBe(1);
expect(console.error.argsForCall[0][0]).toContain(
'Constructor (of Bar) may not invoke super(...) with props that ' +
'differ from the props that were initially passed in from the' +
' component\'s owner.'
);

});

});

0 comments on commit b05ffdd

Please sign in to comment.