@samitouri / QOS-React-2 / commits / 2afd7186ae
Fork 0

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