The library for web and native user interfaces.
Run inner componentDidMount method first
Fixes #76.
Ben Alpert committed
Jun 9, 2013 at 17:21 UTC
2afd7186ae5a8978e9f5fec56031bddca6545c2d
2 files changed
+73
-5
src/core/ReactCompositeComponent.js
+7
-5
@@ -451,17 +451,19 @@ var ReactCompositeComponentMixin = {
451
}
452
}
453
454
- if (this.componentDidMount) {
455
- transaction.getReactOnDOMReady().enqueue(this, this.componentDidMount);
456
- }
457
-
454
this._renderedComponent = this._renderValidatedComponent();
455
456
// Done with mounting, `setState` will now trigger UI changes.
457
this._compositeLifeCycleState = null;
458
this._lifeCycleState = ReactComponent.LifeCycle.MOUNTED;
459
464
- return this._renderedComponent.mountComponent(rootID, transaction);
460
+ var html = this._renderedComponent.mountComponent(rootID, transaction);
461
+
462
+ if (this.componentDidMount) {
463
+ transaction.getReactOnDOMReady().enqueue(this, this.componentDidMount);
464
+ }
465
+
466
+ return html;
467
},
468
469
/**
src/core/__tests__/ReactComponentLifeCycle-test.js
+66
@@ -429,5 +429,71 @@ describe('ReactComponentLifeCycle', function() {
429
expect(instance.state.stateField).toBe('goodbye');
430
});
431
432
+ it('should call nested lifecycle methods in the right order', function() {
433
+ var log;
434
+ var logger = function(msg) {
435
+ return function() {
436
+ // return true for shouldComponentUpdate
437
+ log.push(msg);
438
+ return true;
439
+ };
440
+ };
441
+ var Outer = React.createClass({
442
+ render: function() {
443
+ return <div><Inner x={this.props.x} /></div>;
444
+ },
445
+ componentWillMount: logger('outer componentWillMount'),
446
+ componentDidMount: logger('outer componentDidMount'),
447
+ componentWillReceiveProps: logger('outer componentWillReceiveProps'),
448
+ shouldComponentUpdate: logger('outer shouldComponentUpdate'),
449
+ componentWillUpdate: logger('outer componentWillUpdate'),
450
+ componentDidUpdate: logger('outer componentDidUpdate'),
451
+ componentWillUnmount: logger('outer componentWillUnmount')
452
+ });
453
+ var Inner = React.createClass({
454
+ render: function() {
455
+ return <span>{this.props.x}</span>;
456
+ },
457
+ componentWillMount: logger('inner componentWillMount'),
458
+ componentDidMount: logger('inner componentDidMount'),
459
+ componentWillReceiveProps: logger('inner componentWillReceiveProps'),
460
+ shouldComponentUpdate: logger('inner shouldComponentUpdate'),
461
+ componentWillUpdate: logger('inner componentWillUpdate'),
462
+ componentDidUpdate: logger('inner componentDidUpdate'),
463
+ componentWillUnmount: logger('inner componentWillUnmount')
464
+ });
465
+ var instance;
466
+ var node;
467
+
468
+ log = [];
469
+ instance = ReactTestUtils.renderIntoDocument(<Outer x={17} />);
470
+ expect(log).toEqual([
471
+ 'outer componentWillMount',
472
+ 'inner componentWillMount',
473
+ 'inner componentDidMount',
474
+ 'outer componentDidMount'
475
+ ]);
476
+
477
+ log = [];
478
+ instance.setProps({x: 42});
479
+ expect(log).toEqual([
480
+ 'outer componentWillReceiveProps',
481
+ 'outer shouldComponentUpdate',
482
+ 'outer componentWillUpdate',
483
+ 'inner componentWillReceiveProps',
484
+ 'inner shouldComponentUpdate',
485
+ 'inner componentWillUpdate',
486
+ 'inner componentDidUpdate',
487
+ 'outer componentDidUpdate'
488
+ ]);
489
+
490
+ log = [];
491
+ instance.unmountComponent();
492
+ expect(log).toEqual([
493
+ 'outer componentWillUnmount',
494
+ 'inner componentWillUnmount'
495
+ ]);
496
+ });
497
+
498
});
499