diff --git a/src/core/ReactCompositeComponent.js b/src/core/ReactCompositeComponent.js index dc01652dc4..7edda3b642 100644 --- a/src/core/ReactCompositeComponent.js +++ b/src/core/ReactCompositeComponent.js @@ -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; diff --git a/src/core/__tests__/ReactCompositeComponent-test.js b/src/core/__tests__/ReactCompositeComponent-test.js index d7fa8feb80..a0695f1eed 100644 --- a/src/core/__tests__/ReactCompositeComponent-test.js +++ b/src/core/__tests__/ReactCompositeComponent-test.js @@ -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: [
], + + render: function() { + return ; + } + }); + }).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 ; + } + }); + + React.createClass({ + mixins: [Component], + + render: function() { + return ; + } + }); + }).toThrow( + 'Invariant Violation: ReactCompositeComponent: You\'re attempting to ' + + 'use a component class as a mixin. Instead, just use a regular object.' + ); + }); });