throw when using component/component class as mixin

throw invariant error to help people new to mixins, so that they don't get misled into trying to mixin components into another component
This commit is contained in:
Cheng Lou
2014-01-14 21:11:25 -08:00
committed by Paul O’Shannessy
parent 8ca62bd022
commit 0906d282ec
2 changed files with 60 additions and 12 deletions
+24 -12
View File
@@ -430,6 +430,17 @@ function validateLifeCycleOnReplaceState(instance) {
* specification keys when building `ReactCompositeComponent` classses.
*/
function mixSpecIntoComponent(ConvenienceConstructor, spec) {
invariant(
!isValidClass(spec),
'ReactCompositeComponent: You\'re attempting to ' +
'use a component class as a mixin. Instead, just use a regular object.'
);
invariant(
!ReactComponent.isValidComponent(spec),
'ReactCompositeComponent: You\'re attempting to ' +
'use a component as a mixin. Instead, just use a regular object.'
);
var Constructor = ConvenienceConstructor.componentConstructor;
var proto = Constructor.prototype;
for (var name in spec) {
@@ -1211,6 +1222,18 @@ mixInto(ReactCompositeComponentBase, ReactOwner.Mixin);
mixInto(ReactCompositeComponentBase, ReactPropTransferer.Mixin);
mixInto(ReactCompositeComponentBase, ReactCompositeComponentMixin);
/**
* Checks if a value is a valid component constructor.
*
* @param {*}
* @return {boolean}
* @public
*/
function isValidClass(componentClass) {
return componentClass instanceof Function &&
'componentConstructor' in componentClass &&
componentClass.componentConstructor instanceof Function;
}
/**
* Module for creating composite components.
*
@@ -1274,18 +1297,7 @@ var ReactCompositeComponent = {
return ConvenienceConstructor;
},
/**
* Checks if a value is a valid component constructor.
*
* @param {*}
* @return {boolean}
* @public
*/
isValidClass: function(componentClass) {
return componentClass instanceof Function &&
'componentConstructor' in componentClass &&
componentClass.componentConstructor instanceof Function;
}
isValidClass: isValidClass
};
module.exports = ReactCompositeComponent;
@@ -1068,4 +1068,40 @@ describe('ReactCompositeComponent', function() {
'may be due to a mixin.'
);
});
it("should throw if the mixin is a React component", function() {
expect(function() {
React.createClass({
mixins: [<div />],
render: function() {
return <span />;
}
});
}).toThrow(
'Invariant Violation: ReactCompositeComponent: You\'re attempting to ' +
'use a component as a mixin. Instead, just use a regular object.'
);
});
it("should throw if the mixin is a React component class", function() {
expect(function() {
var Component = React.createClass({
render: function() {
return <span />;
}
});
React.createClass({
mixins: [Component],
render: function() {
return <span />;
}
});
}).toThrow(
'Invariant Violation: ReactCompositeComponent: You\'re attempting to ' +
'use a component class as a mixin. Instead, just use a regular object.'
);
});
});