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

The library for web and native user interfaces.

Add `ReactComponent#isMounted`

There is currently no way for components to know whether or not they are mounted. This means there's no way for callbacks to figure out if they can make certain assumptions (e.g. can `getDOMNode()` or `setState()` be safely invoked). This adds an `isMounted` protected method that lets components properly handle callback behavior when unmounted.

CommitSyncScript committed Jun 13, 2013 at 16:32 UTC aea8e16b4a32d179e70089edde6f1892968cf2b8
3 files changed +24 -9
src/core/ReactComponent.js
+15 -4
@@ -188,6 +188,17 @@ var ReactComponent = {
188 */
189 Mixin: {
190
191 + /**
192 + * Checks whether or not this component is mounted.
193 + *
194 + * @return {boolean} True if mounted, false otherwise.
195 + * @final
196 + * @protected
197 + */
198 + isMounted: function() {
199 + return this._lifeCycleState === ComponentLifeCycle.MOUNTED;
200 + },
201 +
202 /**
203 * Returns the DOM node rendered by this component.
204 *
@@ -201,7 +212,7 @@ var ReactComponent = {
212 'getDOMNode(): The DOM is not supported in the current environment.'
213 );
214 invariant(
204 - this._lifeCycleState === ComponentLifeCycle.MOUNTED,
215 + this.isMounted(),
216 'getDOMNode(): A component must be mounted to have a DOM node.'
217 );
218 var rootNode = this._rootNode;
@@ -329,7 +340,7 @@ var ReactComponent = {
340 */
341 mountComponent: function(rootID, transaction) {
342 invariant(
332 - this._lifeCycleState === ComponentLifeCycle.UNMOUNTED,
343 + !this.isMounted(),
344 'mountComponent(%s, ...): Can only mount an unmounted component.',
345 rootID
346 );
@@ -354,7 +365,7 @@ var ReactComponent = {
365 */
366 unmountComponent: function() {
367 invariant(
357 - this._lifeCycleState === ComponentLifeCycle.MOUNTED,
368 + this.isMounted(),
369 'unmountComponent(): Can only unmount a mounted component.'
370 );
371 var props = this.props;
@@ -378,7 +389,7 @@ var ReactComponent = {
389 */
390 receiveProps: function(nextProps, transaction) {
391 invariant(
381 - this._lifeCycleState === ComponentLifeCycle.MOUNTED,
392 + this.isMounted(),
393 'receiveProps(...): Can only update a mounted component.'
394 );
395 var props = this.props;
src/core/ReactCompositeComponent.js
+2 -2
@@ -548,7 +548,7 @@ var ReactCompositeComponentMixin = {
548 replaceState: function(completeState) {
549 var compositeLifeCycleState = this._compositeLifeCycleState;
550 invariant(
551 - this._lifeCycleState === ReactComponent.LifeCycle.MOUNTED ||
551 + this.isMounted() ||
552 compositeLifeCycleState === CompositeLifeCycle.MOUNTING,
553 'replaceState(...): Can only update a mounted (or mounting) component.'
554 );
@@ -712,7 +712,7 @@ var ReactCompositeComponentMixin = {
712 forceUpdate: function() {
713 var compositeLifeCycleState = this._compositeLifeCycleState;
714 invariant(
715 - this._lifeCycleState === ReactComponent.LifeCycle.MOUNTED,
715 + this.isMounted(),
716 'forceUpdate(...): Can only force an update on mounted components.'
717 );
718 invariant(
src/core/__tests__/ReactNativeComponent-test.js
+7 -3
@@ -241,17 +241,21 @@ describe('ReactNativeComponent', function() {
241
242 var mixInto = require('mixInto');
243 var ReactComponent = require('ReactComponent');
244 + var ReactMultiChild = require('ReactMultiChild');
245 var ReactNativeComponent = require('ReactNativeComponent');
246 var ReactReconcileTransaction = require('ReactReconcileTransaction');
247
247 - var NodeStub = function(initialProps) {
248 + var StubNativeComponent = function(initialProps) {
249 ReactComponent.Mixin.construct.call(this, initialProps);
250 };
250 - mixInto(NodeStub, ReactNativeComponent.Mixin);
251 + mixInto(StubNativeComponent, ReactComponent.Mixin);
252 + mixInto(StubNativeComponent, ReactNativeComponent.Mixin);
253 + mixInto(StubNativeComponent, ReactMultiChild.Mixin);
254
255 mountComponent = function(props) {
256 var transaction = new ReactReconcileTransaction();
254 - return (new NodeStub(props)).mountComponent('test', transaction);
257 + var stubComponent = new StubNativeComponent(props);
258 + return stubComponent.mountComponent('test', transaction);
259 };
260 });
261