Skip to content

Commit

Permalink
ComponentWillUnmount should only ever be invoked once
Browse files Browse the repository at this point in the history
  • Loading branch information
jimfb authored and jim committed Apr 25, 2016
1 parent 7dbc95f commit 008058d
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/renderers/shared/reconciler/ReactCompositeComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ var ReactCompositeComponentMixin = {

// See ReactUpdates and ReactUpdateQueue.
this._pendingCallbacks = null;

// ComponentWillUnmount shall only be called once
this.calledComponentWillUnmount = false;
},

/**
Expand Down Expand Up @@ -405,7 +408,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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1303,4 +1303,38 @@ describe('ReactCompositeComponent', function() {

});

it('should only call componentWillUnmount once', function() {
var app;
var stage = 1;
var count = 0;

class App extends React.Component {
render() {
if(stage === 1) return <UnunmountableComponent />;
else return null;
}
}

class UnunmountableComponent extends React.Component {
componentWillUnmount() {
app.setState({});
count++;
throw Error('always fails');
}

render() {
return <div>Hello {this.props.name}</div>;
}
}

var container = document.createElement('div');

expect(function(){
ReactDOM.render(<App ref={(ref)=>{if(ref) app = ref;}} />, container);
stage = 2;
ReactDOM.render(<App ref={(ref)=>{if(ref) app = ref;}} />, container);
}).toThrow();
expect(count).toBe(1);
});

});

0 comments on commit 008058d

Please sign in to comment.