Merge pull request #2726 from zpao/createElement-undefined-null

Protect better against createElement(null/undefined)
Conflicts:
	src/classic/element/__tests__/ReactElementValidator-test.js
This commit is contained in:
Paul O’Shannessy
2014-12-18 12:30:22 -08:00
parent bbe2e886ab
commit 6526f89235
3 changed files with 50 additions and 17 deletions
+1 -1
View File
@@ -174,7 +174,7 @@ ReactElement.createElement = function(type, config, children) {
}
// Resolve default props
if (type.defaultProps) {
if (type && type.defaultProps) {
var defaultProps = type.defaultProps;
for (propName in defaultProps) {
if (typeof props[propName] === 'undefined') {
+28 -16
View File
@@ -23,6 +23,7 @@ var ReactPropTypeLocations = require('ReactPropTypeLocations');
var ReactCurrentOwner = require('ReactCurrentOwner');
var monitorCodeUse = require('monitorCodeUse');
var warning = require('warning');
/**
* Warn if there's no key explicitly set on dynamic arrays of children or
@@ -220,6 +221,15 @@ function checkPropTypes(componentName, propTypes, props, location) {
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).'
);
var element = ReactElement.createElement.apply(this, arguments);
// The result can be nullish if a mock or a custom function is used.
@@ -232,22 +242,24 @@ var ReactElementValidator = {
validateChildKeys(arguments[i], type);
}
var name = type.displayName;
if (type.propTypes) {
checkPropTypes(
name,
type.propTypes,
element.props,
ReactPropTypeLocations.prop
);
}
if (type.contextTypes) {
checkPropTypes(
name,
type.contextTypes,
element._context,
ReactPropTypeLocations.context
);
if (type) {
var name = type.displayName;
if (type.propTypes) {
checkPropTypes(
name,
type.propTypes,
element.props,
ReactPropTypeLocations.prop
);
}
if (type.contextTypes) {
checkPropTypes(
name,
type.contextTypes,
element._context,
ReactPropTypeLocations.context
);
}
}
return element;
},
@@ -1483,4 +1483,25 @@ describe('ReactCompositeComponent', function() {
);
});
it('gives a helpful error when passing null or undefined', function() {
spyOn(console, 'warn');
React.createElement(undefined);
React.createElement(null);
expect(console.warn.calls.length).toBe(2);
expect(console.warn.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).'
);
expect(console.warn.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).'
);
React.createElement('div');
expect(console.warn.calls.length).toBe(2);
expect(() => React.createElement(undefined)).not.toThrow()
});
});