diff --git a/src/index.js b/src/index.js index 209f20c..b945ce9 100644 --- a/src/index.js +++ b/src/index.js @@ -359,16 +359,19 @@ let findDOMNode = component => component && component.base || component; function F(){} function createClass(obj) { - let mixins = obj.mixins && collateMixins(obj.mixins); + obj = extend({}, obj); function cl(props, context) { extend(this, obj); - if (mixins) applyMixins(this, mixins); Component.call(this, props, context, BYPASS_HOOK); bindAll(this); newComponentHook.call(this, props, context); } + let mixins = obj.mixins && collateMixins(obj.mixins); + // We need to apply mixins here so that getDefaultProps is correctly mixed + if (mixins) applyMixins(obj, mixins); + if (obj.statics) { extend(cl, obj.statics); } diff --git a/test/component.js b/test/component.js index 065cfd4..ca7c0c8 100644 --- a/test/component.js +++ b/test/component.js @@ -239,6 +239,45 @@ describe('components', () => { }); describe("mixins", () => { + describe("getDefaultProps", () => { + it('should combine the results', () => { + const Foo = React.createClass({ + mixins: [ + { getDefaultProps: () => ({ a: true }) }, + { getDefaultProps: () => ({ b: true }) } + ], + getDefaultProps() { + return { c: true }; + }, + render() { + return
; + } + }); + + expect(Foo.defaultProps).to.eql({ + a: true, + b: true, + c: true + }); + }); + + it('should throw an error for duplicate keys', () => { + expect(() => { + const Foo = React.createClass({ + mixins: [ + { getDefaultProps: () => ({ a: true }) } + ], + getDefaultProps() { + return { a: true }; + }, + render() { + return
; + } + }); + }).to.throw(); + }); + }); + describe("getInitialState", () => { it('should combine the results', () => { const Foo = React.createClass({