diff --git a/src/renderers/shared/reconciler/ReactCompositeComponent.js b/src/renderers/shared/reconciler/ReactCompositeComponent.js index 4cb8633c91b92..25b100f2cf68e 100644 --- a/src/renderers/shared/reconciler/ReactCompositeComponent.js +++ b/src/renderers/shared/reconciler/ReactCompositeComponent.js @@ -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; @@ -195,6 +196,22 @@ var ReactCompositeComponentMixin = { Component.displayName || Component.name || 'Component' ); } + + var instPropsNotReactElements = !ReactElement.isValidElement(inst.props); + var publicPropsNotReactElements = !ReactElement.isValidElement(publicProps); + var propsMutated = !shallowEqual(inst.props || {}, publicProps); + var componentName = Component.displayName || Component.name || + 'Component'; + + warning( + typeof inst.props === 'undefined' || + !instPropsNotReactElements || + !publicPropsNotReactElements || + !propsMutated, + '%s(...): When calling super() in `%s`, make sure to pass ' + + 'up the same props that your component\'s constructor was passed.', + componentName, componentName + ); } // These should be set up in the constructor, but as a convenience for diff --git a/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js b/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js index 298c5a1be2277..91a1f445e27ee 100644 --- a/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js +++ b/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js @@ -1241,4 +1241,31 @@ describe('ReactCompositeComponent', function() { }); + it('should warn when mutated props are passed', function() { + + var container = document.createElement('div'); + + class Foo extends React.Component { + constructor(props) { + var _props = { idx: props.idx + '!' }; + super(_props); + } + + render() { + return ; + } + } + + expect(console.error.calls.length).toBe(0); + + ReactDOM.render(, container); + + expect(console.error.calls.length).toBe(1); + expect(console.error.argsForCall[0][0]).toContain( + 'Foo(...): When calling super() in `Foo`, make sure to pass ' + + 'up the same props that your component\'s constructor was passed.' + ); + + }); + });