Skip to content

Commit

Permalink
[ReactNative] introduce mountSafeCallback
Browse files Browse the repository at this point in the history
Summary:
`mountSafeCallback` simply wraps a callback in an `isMounted()` check to prevent crashes when old callbacks are called on unmounted components.

@public

Test Plan:
Added logging and made sure callbacks were getting called through
`mountSafeCallback` and that things worked (e.g. photo viewer rotation etc).
  • Loading branch information
sahrens committed May 14, 2015
1 parent a6b29a0 commit 6e179fb
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
16 changes: 12 additions & 4 deletions Libraries/ReactIOS/NativeMethodsMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var findNodeHandle = require('findNodeHandle');
var flattenStyle = require('flattenStyle');
var invariant = require('invariant');
var mergeFast = require('mergeFast');
var mountSafeCallback = require('mountSafeCallback');
var precomputeStyle = require('precomputeStyle');

type MeasureOnSuccessCallback = (
Expand Down Expand Up @@ -52,7 +53,11 @@ var animationIDInvariant = function(
var NativeMethodsMixin = {
addAnimation: function(anim: number, callback?: (finished: bool) => void) {
animationIDInvariant('addAnimation', anim);
RCTPOPAnimationManager.addAnimation(findNodeHandle(this), anim, callback);
RCTPOPAnimationManager.addAnimation(
findNodeHandle(this),
anim,
mountSafeCallback(this, callback)
);
},

removeAnimation: function(anim: number) {
Expand All @@ -61,7 +66,10 @@ var NativeMethodsMixin = {
},

measure: function(callback: MeasureOnSuccessCallback) {
RCTUIManager.measure(findNodeHandle(this), callback);
RCTUIManager.measure(
findNodeHandle(this),
mountSafeCallback(this, callback)
);
},

measureLayout: function(
Expand All @@ -72,8 +80,8 @@ var NativeMethodsMixin = {
RCTUIManager.measureLayout(
findNodeHandle(this),
relativeToNativeNode,
onFail,
onSuccess
mountSafeCallback(this, onFail),
mountSafeCallback(this, onSuccess)
);
},

Expand Down
23 changes: 23 additions & 0 deletions Libraries/Utilities/mountSafeCallback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule mountSafeCallback
* @flow
*/
'use strict';

var mountSafeCallback = function(context: ReactComponent, callback: ?Function): any {
return function() {
if (!callback || !context.isMounted()) {
return;
}
return callback.apply(context, arguments);
};
};

module.exports = mountSafeCallback;

0 comments on commit 6e179fb

Please sign in to comment.