diff --git a/src/core/ReactCompositeComponent.js b/src/core/ReactCompositeComponent.js index e97b5439fc..df9e5bbd78 100644 --- a/src/core/ReactCompositeComponent.js +++ b/src/core/ReactCompositeComponent.js @@ -326,8 +326,9 @@ function validateMethodOverride(proto, name) { function validateLifeCycleOnReplaceState(instance) { var compositeLifeCycleState = instance._compositeLifeCycleState; invariant( - instance.isMounted(), - 'replaceState(...): Can only update a mounted component.' + instance.isMounted() || + compositeLifeCycleState === CompositeLifeCycle.MOUNTING, + 'replaceState(...): Can only update a mounted or mounting component.' ); invariant( compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE && @@ -480,6 +481,17 @@ var ReactCompositeComponentMixin = { ReactCurrentOwner.getDepth() + 1 : 0; }, + /** + * Checks whether or not this composite component is mounted. + * @return {boolean} True if mounted, false otherwise. + * @protected + * @final + */ + isMounted: function() { + return ReactComponent.Mixin.isMounted.call(this) && + this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING; + }, + /** * Initializes the component, renders markup, and registers event listeners. * @@ -756,8 +768,10 @@ var ReactCompositeComponentMixin = { forceUpdate: function() { var compositeLifeCycleState = this._compositeLifeCycleState; invariant( - this.isMounted(), - 'forceUpdate(...): Can only force an update on mounted components.' + this.isMounted() || + compositeLifeCycleState === CompositeLifeCycle.MOUNTING, + 'forceUpdate(...): Can only force an update on mounted or mounting ' + + 'components.' ); invariant( compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE && diff --git a/src/core/__tests__/ReactComponent-test.js b/src/core/__tests__/ReactComponent-test.js index a753ce0c89..5b1d96a9e2 100644 --- a/src/core/__tests__/ReactComponent-test.js +++ b/src/core/__tests__/ReactComponent-test.js @@ -95,4 +95,23 @@ describe('ReactComponent', function() { ReactTestUtils.renderIntoDocument(instance); }); + it('should correctly determine if a component is mounted', function() { + var Component = React.createClass({ + componentWillMount: function() { + expect(this.isMounted()).toBeFalsy(); + }, + componentDidMount: function() { + expect(this.isMounted()).toBeTruthy(); + }, + render: function() { + return
; + } + }); + + var instance =