diff --git a/src/classic/element/ReactElementValidator.js b/src/classic/element/ReactElementValidator.js index bd961d4d62..bb1f21066a 100644 --- a/src/classic/element/ReactElementValidator.js +++ b/src/classic/element/ReactElementValidator.js @@ -362,7 +362,8 @@ function checkAndWarnForMutatedProps(element) { * @param {ReactElement} element */ function validatePropTypes(element) { - if (element.type == null) { + if (!(typeof element.type === 'string' || + typeof element.type === 'function')) { // This has already warned. Don't throw. return; } @@ -398,11 +399,10 @@ var ReactElementValidator = { createElement: function(type, props, children) { // We warn in this case but don't throw. We expect the element creation to // succeed and there will likely be errors in render. - warning( - type != null, - 'React.createElement: type should not be null or undefined. It should ' + - 'be a string (for DOM elements) or a ReactClass (for composite ' + - 'components).%s', + warning(typeof type === 'string' || typeof type === 'function', + 'React.createElement: type should not be null, undefined, boolean, or ' + + 'number. It should be a string (for DOM elements) or a ReactClass ' + + '(for composite components).%s', getDeclarationErrorAddendum() ); diff --git a/src/classic/element/__tests__/ReactElementValidator-test.js b/src/classic/element/__tests__/ReactElementValidator-test.js index bd908c4bf4..ef550c0ea4 100644 --- a/src/classic/element/__tests__/ReactElementValidator-test.js +++ b/src/classic/element/__tests__/ReactElementValidator-test.js @@ -258,26 +258,40 @@ describe('ReactElementValidator', function() { ); }); - it('gives a helpful error when passing null or undefined', function() { + it('gives a helpful error when passing null, undefined, boolean, or number', + () => { spyOn(console, 'error'); React.createElement(undefined); React.createElement(null); - expect(console.error.calls.length).toBe(2); + React.createElement(true); + React.createElement(123); + expect(console.error.calls.length).toBe(4); expect(console.error.calls[0].args[0]).toBe( - 'Warning: React.createElement: type should not be null or undefined. ' + - 'It should be a string (for DOM elements) or a ReactClass (for ' + - 'composite components).' + 'Warning: React.createElement: type should not be null, undefined, ' + + 'boolean, or number. It should be a string (for DOM elements) or a ' + + 'ReactClass (for composite components).' ); expect(console.error.calls[1].args[0]).toBe( - 'Warning: React.createElement: type should not be null or undefined. ' + - 'It should be a string (for DOM elements) or a ReactClass (for ' + - 'composite components).' + 'Warning: React.createElement: type should not be null, undefined, ' + + 'boolean, or number. It should be a string (for DOM elements) or a ' + + 'ReactClass (for composite components).' + ); + expect(console.error.calls[2].args[0]).toBe( + 'Warning: React.createElement: type should not be null, undefined, ' + + 'boolean, or number. It should be a string (for DOM elements) or a ' + + 'ReactClass (for composite components).' + ); + expect(console.error.calls[3].args[0]).toBe( + 'Warning: React.createElement: type should not be null, undefined, ' + + 'boolean, or number. It should be a string (for DOM elements) or a ' + + 'ReactClass (for composite components).' ); React.createElement('div'); - expect(console.error.calls.length).toBe(2); + expect(console.error.calls.length).toBe(4); }); - it('includes the owner name when passing null or undefined', function() { + it('includes the owner name when passing null, undefined, boolean, or number', + () => { spyOn(console, 'error'); var ParentComp = React.createClass({ render: function() { @@ -289,9 +303,10 @@ describe('ReactElementValidator', function() { }).toThrow(); expect(console.error.calls.length).toBe(2); expect(console.error.calls[0].args[0]).toBe( - 'Warning: React.createElement: type should not be null or undefined. ' + - 'It should be a string (for DOM elements) or a ReactClass (for ' + - 'composite components). Check the render method of `ParentComp`.' + 'Warning: React.createElement: type should not be null, undefined, ' + + 'boolean, or number. It should be a string (for DOM elements) or a ' + + 'ReactClass (for composite components). Check the render method of ' + + '`ParentComp`.' ); expect(console.error.calls[1].args[0]).toBe( 'Warning: Only functions or strings can be mounted as React components.' diff --git a/src/modern/element/__tests__/ReactJSXElementValidator-test.js b/src/modern/element/__tests__/ReactJSXElementValidator-test.js index b3cf895158..1e15d2d3b9 100644 --- a/src/modern/element/__tests__/ReactJSXElementValidator-test.js +++ b/src/modern/element/__tests__/ReactJSXElementValidator-test.js @@ -208,24 +208,36 @@ describe('ReactJSXElementValidator', function() { ); }); - it('gives a helpful error when passing null or undefined', function() { + it('gives a helpful error when passing null, undefined, or boolean', () => { var Undefined = undefined; var Null = null; + var True = true; + var Num = 123; var Div = 'div'; spyOn(console, 'error'); ; ; - expect(console.error.calls.length).toBe(2); + ; + ; + expect(console.error.calls.length).toBe(4); expect(console.error.calls[0].args[0]).toContain( - 'type should not be null or undefined. It should be a string (for ' + - 'DOM elements) or a ReactClass (for composite components).' + 'type should not be null, undefined, boolean, or number. It should be ' + + 'a string (for DOM elements) or a ReactClass (for composite components).' ); expect(console.error.calls[1].args[0]).toContain( - 'type should not be null or undefined. It should be a string (for ' + - 'DOM elements) or a ReactClass (for composite components).' + 'type should not be null, undefined, boolean, or number. It should be ' + + 'a string (for DOM elements) or a ReactClass (for composite components).' + ); + expect(console.error.calls[2].args[0]).toContain( + 'type should not be null, undefined, boolean, or number. It should be ' + + 'a string (for DOM elements) or a ReactClass (for composite components).' + ); + expect(console.error.calls[3].args[0]).toContain( + 'type should not be null, undefined, boolean, or number. It should be ' + + 'a string (for DOM elements) or a ReactClass (for composite components).' );
; - expect(console.error.calls.length).toBe(2); + expect(console.error.calls.length).toBe(4); }); it('should check default prop values', function() {