mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Improve error message when mounting non-string/function elements
This commit is contained in:
@@ -327,17 +327,18 @@ describe('ReactElementValidator', function() {
|
||||
});
|
||||
expect(function() {
|
||||
ReactTestUtils.renderIntoDocument(React.createElement(ParentComp));
|
||||
}).toThrow();
|
||||
expect(console.error.calls.length).toBe(2);
|
||||
}).toThrow(
|
||||
'Invariant Violation: Element 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`.'
|
||||
);
|
||||
expect(console.error.calls.length).toBe(1);
|
||||
expect(console.error.calls[0].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). 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.'
|
||||
);
|
||||
});
|
||||
|
||||
it('should check default prop values', function() {
|
||||
|
||||
@@ -279,4 +279,32 @@ describe('ReactComponent', function() {
|
||||
);
|
||||
});
|
||||
|
||||
it('throws usefully when rendering badly-typed elements', function() {
|
||||
spyOn(console, 'error');
|
||||
|
||||
var X = undefined;
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<X />)).toThrow(
|
||||
'Invariant Violation: Element type is invalid: expected a string (for ' +
|
||||
'built-in components) or a class/function (for composite components) ' +
|
||||
'but got: undefined.'
|
||||
);
|
||||
|
||||
var Y = null;
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<Y />)).toThrow(
|
||||
'Invariant Violation: Element type is invalid: expected a string (for ' +
|
||||
'built-in components) or a class/function (for composite components) ' +
|
||||
'but got: null.'
|
||||
);
|
||||
|
||||
var Z = {};
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<Z />)).toThrow(
|
||||
'Invariant Violation: Element type is invalid: expected a string (for ' +
|
||||
'built-in components) or a class/function (for composite components) ' +
|
||||
'but got: object.'
|
||||
);
|
||||
|
||||
// One warning for each element creation
|
||||
expect(console.error.calls.length).toBe(3);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -30,6 +30,16 @@ assign(
|
||||
}
|
||||
);
|
||||
|
||||
function getDeclarationErrorAddendum(owner) {
|
||||
if (owner) {
|
||||
var name = owner.getName();
|
||||
if (name) {
|
||||
return ' Check the render method of `' + name + '`.';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the type reference is a known internal type. I.e. not a user
|
||||
* provided composite type.
|
||||
@@ -63,13 +73,14 @@ function instantiateReactComponent(node, parentCompositeType) {
|
||||
|
||||
if (typeof node === 'object') {
|
||||
var element = node;
|
||||
if (__DEV__) {
|
||||
warning(
|
||||
element && (typeof element.type === 'function' ||
|
||||
typeof element.type === 'string'),
|
||||
'Only functions or strings can be mounted as React components.'
|
||||
);
|
||||
}
|
||||
invariant(
|
||||
element && (typeof element.type === 'function' ||
|
||||
typeof element.type === 'string'),
|
||||
'Element type is invalid: expected a string (for built-in components) ' +
|
||||
'or a class/function (for composite components) but got: %s.%s',
|
||||
element.type == null ? element.type : typeof element.type,
|
||||
getDeclarationErrorAddendum(element._owner)
|
||||
);
|
||||
|
||||
// Special case string values
|
||||
if (parentCompositeType === element.type &&
|
||||
|
||||
Reference in New Issue
Block a user