diff --git a/src/classic/class/ReactClass.js b/src/classic/class/ReactClass.js index e4cc79f1ec..aa0f379bf9 100644 --- a/src/classic/class/ReactClass.js +++ b/src/classic/class/ReactClass.js @@ -327,11 +327,13 @@ var RESERVED_SPEC_KEYS = { } }, childContextTypes: function(Constructor, childContextTypes) { - validateTypeDef( - Constructor, - childContextTypes, - ReactPropTypeLocations.childContext - ); + if (__DEV__) { + validateTypeDef( + Constructor, + childContextTypes, + ReactPropTypeLocations.childContext + ); + } Constructor.childContextTypes = assign( {}, Constructor.childContextTypes, @@ -339,11 +341,13 @@ var RESERVED_SPEC_KEYS = { ); }, contextTypes: function(Constructor, contextTypes) { - validateTypeDef( - Constructor, - contextTypes, - ReactPropTypeLocations.context - ); + if (__DEV__) { + validateTypeDef( + Constructor, + contextTypes, + ReactPropTypeLocations.context + ); + } Constructor.contextTypes = assign( {}, Constructor.contextTypes, @@ -365,11 +369,13 @@ var RESERVED_SPEC_KEYS = { } }, propTypes: function(Constructor, propTypes) { - validateTypeDef( - Constructor, - propTypes, - ReactPropTypeLocations.prop - ); + if (__DEV__) { + validateTypeDef( + Constructor, + propTypes, + ReactPropTypeLocations.prop + ); + } Constructor.propTypes = assign( {}, Constructor.propTypes, @@ -384,7 +390,9 @@ var RESERVED_SPEC_KEYS = { function validateTypeDef(Constructor, typeDef, location) { for (var propName in typeDef) { if (typeDef.hasOwnProperty(propName)) { - invariant( + // use a warning instead of an invariant so components + // don't show up in prod but not in __DEV__ + warning( typeof typeDef[propName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', diff --git a/src/classic/class/__tests__/ReactClass-test.js b/src/classic/class/__tests__/ReactClass-test.js index b0d3b45b5a..c48b693034 100644 --- a/src/classic/class/__tests__/ReactClass-test.js +++ b/src/classic/class/__tests__/ReactClass-test.js @@ -74,8 +74,11 @@ describe('ReactClass-spec', function() { .toBe(propValidator); }); - it('should throw on invalid prop types', function() { - expect(function() { + it('should warn on invalid prop types', function() { + var warn = console.warn; + console.warn = mocks.getMockFunction(); + try { + React.createClass({ displayName: 'Component', propTypes: { @@ -85,14 +88,20 @@ describe('ReactClass-spec', function() { return {this.props.prop}; } }); - }).toThrow( - 'Invariant Violation: Component: prop type `prop` is invalid; ' + - 'it must be a function, usually from React.PropTypes.' - ); + expect(console.warn.mock.calls.length).toBe(1); + expect(console.warn.mock.calls[0][0]).toBe( + 'Warning: Component: prop type `prop` is invalid; ' + + 'it must be a function, usually from React.PropTypes.' + ); + } finally { + console.warn = warn; + } }); - it('should throw on invalid context types', function() { - expect(function() { + it('should warn on invalid context types', function() { + var warn = console.warn; + console.warn = mocks.getMockFunction(); + try { React.createClass({ displayName: 'Component', contextTypes: { @@ -102,14 +111,20 @@ describe('ReactClass-spec', function() { return {this.props.prop}; } }); - }).toThrow( - 'Invariant Violation: Component: context type `prop` is invalid; ' + - 'it must be a function, usually from React.PropTypes.' - ); + expect(console.warn.mock.calls.length).toBe(1); + expect(console.warn.mock.calls[0][0]).toBe( + 'Warning: Component: context type `prop` is invalid; ' + + 'it must be a function, usually from React.PropTypes.' + ); + } finally { + console.warn = warn; + } }); it('should throw on invalid child context types', function() { - expect(function() { + var warn = console.warn; + console.warn = mocks.getMockFunction(); + try { React.createClass({ displayName: 'Component', childContextTypes: { @@ -119,10 +134,14 @@ describe('ReactClass-spec', function() { return {this.props.prop}; } }); - }).toThrow( - 'Invariant Violation: Component: child context type `prop` is invalid; ' + - 'it must be a function, usually from React.PropTypes.' - ); + expect(console.warn.mock.calls.length).toBe(1); + expect(console.warn.mock.calls[0][0]).toBe( + 'Warning: Component: child context type `prop` is invalid; ' + + 'it must be a function, usually from React.PropTypes.' + ); + } finally { + console.warn = warn; + } }); it('should warn when mispelling shouldComponentUpdate', function() { diff --git a/src/classic/element/ReactElementValidator.js b/src/classic/element/ReactElementValidator.js index f264318fa1..06b9fc2b5c 100644 --- a/src/classic/element/ReactElementValidator.js +++ b/src/classic/element/ReactElementValidator.js @@ -381,13 +381,15 @@ var ReactElementValidator = { element ); var name = componentClass.displayName || componentClass.name; - if (componentClass.propTypes) { - checkPropTypes( - name, - componentClass.propTypes, - element.props, - ReactPropTypeLocations.prop - ); + if (__DEV__) { + if (componentClass.propTypes) { + checkPropTypes( + name, + componentClass.propTypes, + element.props, + ReactPropTypeLocations.prop + ); + } } if (typeof componentClass.getDefaultProps === 'function') { warning(