Change:
Right now we don't do this consistently, so you could have behavior that varies depending on where you put the key in your class spec. That's not great. Here's an example: (using master) This outputs: I think we should consistently behave like CompB (component, then mixin methods) but disagrees. Any other opinions. Potentially interested (once we figure out which way we go)? This is relatively contained and testable but it does take you right into core.
Doing mixins first is more intuitive to me because that's normally how people write the specs (in my experience, at least).
Hi, thanks for the mention. I'd like to take on this if nobody minds. I agree with that calling mixins first is more intuitive.
Go for it! Let me know if you have any questions; I'm happy to help.
OK great. I'll try to do it tomorrow.
Mention me if there's something else I can take. I liked that although this task had a small scope, it introduced me to the way actually works and how spec transforms into a component instance. It would be cool if I could take a few small tasks in other areas (rendering, batching) that introduce me to these areas.

Discussion:
); ``` <del> A nice feature of mixins is that if a component is using multiple mixins and several mixins define the same lifecycle method (i.e. several mixins want to do some cleanup when the component is destroyed), all of the lifecycle methods are guaranteed to be called. </del> <ins> A nice feature of mixins is that if a component is using multiple mixins and several mixins define the same lifecycle method (i.e. several mixins want to do some cleanup when the component is destroyed), all of the lifecycle methods are guaranteed to be called. Methods defined on mixins run in the order mixins were listed, followed by a method call on the component. </ins>

var instantiateReactComponent = require('instantiateReactComponent'); var invariant = require('invariant'); var keyMirror = require('keyMirror'); <ins> var keyOf = require('keyOf'); </ins> var merge = require('merge'); var mixInto = require('mixInto'); var monitorCodeUse = require('monitorCodeUse');

var shouldUpdateReactComponent = require('shouldUpdateReactComponent'); var warning = require('warning'); <ins> var MIXINS_KEY = keyOf({mixins: null}); </ins> /** * Policies that describe methods in `ReactCompositeComponentInterface`. */

var Constructor = ConvenienceConstructor.type; var proto = Constructor.prototype; <ins> // By handling mixins before any other properties, we ensure the same // chaining order is applied to methods with DEFINE_MANY policy, whether // mixins are listed before or after these methods in the spec. if (spec.hasOwnProperty(MIXINS_KEY)) { RESERVED_SPEC_KEYS.mixins(ConvenienceConstructor, spec.mixins); } </ins> for (var name in spec) { <del> var property = spec[name]; </del> if (!spec.hasOwnProperty(name)) { continue; } <ins> if (name === MIXINS_KEY) { // We have already handled mixins in a special case above continue; } var property = spec[name]; </ins> validateMethodOverride(proto, name); if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {

var TestComponent; var TestComponentWithPropTypes; <ins> var TestComponentWithReverseSpec; </ins> var mixinPropValidator; var componentPropValidator;

} }; <ins> var MixinBWithReverseSpec = { componentDidMount: function() { this.props.listener('MixinBWithReverseSpec didMount'); }, mixins: [MixinA] }; </ins> var MixinC = { statics: { staticC: function() {}

} }); <ins> TestComponentWithReverseSpec = React.createClass({ render: function() { return <div />; }, componentDidMount: function() { this.props.listener('Component didMount'); }, mixins: [MixinBWithReverseSpec, MixinC, MixinD] }); </ins> TestComponentWithPropTypes = React.createClass({ mixins: [MixinD], propTypes: {

]); }); <ins> it('should chain functions regardless of spec property order', function() { var listener = mocks.getMockFunction(); var instance = <TestComponentWithReverseSpec listener={listener} />; instance = ReactTestUtils.renderIntoDocument(instance); expect(listener.mock.calls).toEqual([ ['MixinA didMount'], ['MixinBWithReverseSpec didMount'], ['MixinC didMount'], ['Component didMount'] ]); }); </ins> it('should validate prop types via mixins', function() { expect(TestComponent.type.propTypes).toBeDefined(); expect(TestComponent.type.propTypes.value)