Skip to content

Commit

Permalink
Reset instance vars before calling commit phase lifecycles
Browse files Browse the repository at this point in the history
  • Loading branch information
acdlite committed Aug 17, 2017
1 parent 072b1d9 commit 834938e
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/renderers/shared/fiber/ReactFiberCommitWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
if (__DEV__) {
var callComponentWillUnmountWithTimerInDev = function(current, instance) {
startPhaseTimer(current, 'componentWillUnmount');
instance.props = current.memoizedProps;
instance.state = current.memoizedState;
instance.componentWillUnmount();
stopPhaseTimer();
};
Expand All @@ -87,6 +89,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
}
} else {
try {
instance.props = current.memoizedProps;
instance.state = current.memoizedState;
instance.componentWillUnmount();
} catch (unmountError) {
captureError(current, unmountError);
Expand Down Expand Up @@ -495,6 +499,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
if (__DEV__) {
startPhaseTimer(finishedWork, 'componentDidMount');
}
instance.props = finishedWork.memoizedProps;
instance.state = finishedWork.memoizedState;
instance.componentDidMount();
if (__DEV__) {
stopPhaseTimer();
Expand All @@ -505,6 +511,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
if (__DEV__) {
startPhaseTimer(finishedWork, 'componentDidUpdate');
}
instance.props = finishedWork.memoizedProps;
instance.state = finishedWork.memoizedState;
instance.componentDidUpdate(prevProps, prevState);
if (__DEV__) {
stopPhaseTimer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1123,4 +1123,41 @@ describe('ReactIncrementalErrorHandling', () => {
);
});
});

it('resets instance variables before unmounting failed node', () => {
spyOn(console, 'error');

class ErrorBoundary extends React.Component {
state = {error: null};
componentDidCatch(error) {
this.setState({error});
}
render() {
return this.state.error ? null : this.props.children;
}
}
class Foo extends React.Component {
state = {step: 0};
componentDidMount() {
this.setState({step: 1});
}
componentWillUnmount() {
ReactNoop.yield('componentWillUnmount: ' + this.state.step);
}
render() {
ReactNoop.yield('render: ' + this.state.step);
if (this.state.step > 0) {
throw new Error('oops');
}
return null;
}
}

ReactNoop.render(<ErrorBoundary><Foo /></ErrorBoundary>);
expect(ReactNoop.flush()).toEqual([
'render: 0',
'render: 1',
'componentWillUnmount: 0',
]);
});
});

0 comments on commit 834938e

Please sign in to comment.