diff --git a/src/renderers/shared/reconciler/ReactCompositeComponent.js b/src/renderers/shared/reconciler/ReactCompositeComponent.js
index 26d1c8fb6e709..0f8574545a075 100644
--- a/src/renderers/shared/reconciler/ReactCompositeComponent.js
+++ b/src/renderers/shared/reconciler/ReactCompositeComponent.js
@@ -132,6 +132,9 @@ var ReactCompositeComponentMixin = {
// See ReactUpdates and ReactUpdateQueue.
this._pendingCallbacks = null;
+
+ // ComponentWillUnmount shall only be called once
+ this._calledComponentWillUnmount = false;
},
/**
@@ -416,7 +419,8 @@ var ReactCompositeComponentMixin = {
}
var inst = this._instance;
- if (inst.componentWillUnmount) {
+ if (inst.componentWillUnmount && !inst._calledComponentWillUnmount) {
+ inst._calledComponentWillUnmount = true;
if (safely) {
var name = this.getName() + '.componentWillUnmount()';
ReactErrorUtils.invokeGuardedCallback(name, inst.componentWillUnmount.bind(inst));
diff --git a/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js b/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js
index c33fb33b25382..5568ae33931ba 100644
--- a/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js
+++ b/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js
@@ -1303,4 +1303,45 @@ describe('ReactCompositeComponent', function() {
});
+ it('should only call componentWillUnmount once', function() {
+ var app;
+ var count = 0;
+
+ class App extends React.Component {
+ render() {
+ if (this.props.stage === 1) {
+ return