diff --git a/src/isomorphic/classic/element/ReactElementValidator.js b/src/isomorphic/classic/element/ReactElementValidator.js
index 8c30884017..e7ad9d72a7 100644
--- a/src/isomorphic/classic/element/ReactElementValidator.js
+++ b/src/isomorphic/classic/element/ReactElementValidator.js
@@ -187,13 +187,31 @@ var ReactElementValidator = {
// We warn in this case but don't throw. We expect the element creation to
// succeed and there will likely be errors in render.
if (!validType) {
- warning(
- false,
- '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()
- );
+ if (
+ typeof type !== 'function' &&
+ typeof type !== 'string'
+ ) {
+ var info = '';
+ if (
+ type === undefined ||
+ typeof type === 'object' &&
+ type !== null &&
+ Object.keys(type).length === 0
+ ) {
+ info +=
+ ' You likely forgot to export your component from the file ' +
+ 'it\'s defined in.';
+ }
+ info += getDeclarationErrorAddendum();
+ warning(
+ false,
+ 'React.createElement: type is invalid -- expected a string (for ' +
+ 'built-in components) or a class/function (for composite ' +
+ 'components) but got: %s.%s',
+ type == null ? type : typeof type,
+ info,
+ );
+ }
}
var element = ReactElement.createElement.apply(this, arguments);
diff --git a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js
index 5690e2125b..b36fa2f39c 100644
--- a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js
+++ b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js
@@ -289,35 +289,49 @@ describe('ReactElementValidator', () => {
);
});
- it('gives a helpful error when passing null, undefined, boolean, or number', () => {
+ it('gives a helpful error when passing invalid types', () => {
spyOn(console, 'error');
React.createElement(undefined);
React.createElement(null);
React.createElement(true);
React.createElement(123);
- expect(console.error.calls.count()).toBe(4);
+ React.createElement({x: 17});
+ React.createElement({});
+ expect(console.error.calls.count()).toBe(6);
expect(console.error.calls.argsFor(0)[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).'
+ 'Warning: React.createElement: type is invalid -- expected a string ' +
+ '(for built-in components) or a class/function (for composite ' +
+ 'components) but got: undefined. You likely forgot to export your ' +
+ 'component from the file it\'s defined in.'
);
expect(console.error.calls.argsFor(1)[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).'
+ 'Warning: React.createElement: type is invalid -- expected a string ' +
+ '(for built-in components) or a class/function (for composite ' +
+ 'components) but got: null.'
);
expect(console.error.calls.argsFor(2)[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).'
+ 'Warning: React.createElement: type is invalid -- expected a string ' +
+ '(for built-in components) or a class/function (for composite ' +
+ 'components) but got: boolean.'
);
expect(console.error.calls.argsFor(3)[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).'
+ 'Warning: React.createElement: type is invalid -- expected a string ' +
+ '(for built-in components) or a class/function (for composite ' +
+ 'components) but got: number.'
+ );
+ expect(console.error.calls.argsFor(4)[0]).toBe(
+ 'Warning: React.createElement: type is invalid -- expected a string ' +
+ '(for built-in components) or a class/function (for composite ' +
+ 'components) but got: object.'
+ );
+ expect(console.error.calls.argsFor(5)[0]).toBe(
+ 'Warning: React.createElement: type is invalid -- expected a string ' +
+ '(for built-in components) or a class/function (for composite ' +
+ 'components) but got: object. You likely forgot to export your ' +
+ 'component from the file it\'s defined in.'
);
React.createElement('div');
- expect(console.error.calls.count()).toBe(4);
+ expect(console.error.calls.count()).toBe(6);
});
it('includes the owner name when passing null, undefined, boolean, or number', () => {
@@ -336,10 +350,9 @@ describe('ReactElementValidator', () => {
);
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[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). Check the render method of ' +
- '`ParentComp`.'
+ 'Warning: React.createElement: type is invalid -- expected a string ' +
+ '(for built-in components) or a class/function (for composite ' +
+ 'components) but got: null. Check the render method of `ParentComp`.'
);
});
@@ -537,9 +550,10 @@ describe('ReactElementValidator', () => {
void