From 834938e0b04c9250553ec81248f784f5020c5fef Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Thu, 17 Aug 2017 13:17:29 -0700 Subject: [PATCH] Reset instance vars before calling commit phase lifecycles --- .../shared/fiber/ReactFiberCommitWork.js | 8 ++++ .../ReactIncrementalErrorHandling-test.js | 37 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/renderers/shared/fiber/ReactFiberCommitWork.js b/src/renderers/shared/fiber/ReactFiberCommitWork.js index d6ed708926b45..e90da861065e0 100644 --- a/src/renderers/shared/fiber/ReactFiberCommitWork.js +++ b/src/renderers/shared/fiber/ReactFiberCommitWork.js @@ -66,6 +66,8 @@ module.exports = function( if (__DEV__) { var callComponentWillUnmountWithTimerInDev = function(current, instance) { startPhaseTimer(current, 'componentWillUnmount'); + instance.props = current.memoizedProps; + instance.state = current.memoizedState; instance.componentWillUnmount(); stopPhaseTimer(); }; @@ -87,6 +89,8 @@ module.exports = function( } } else { try { + instance.props = current.memoizedProps; + instance.state = current.memoizedState; instance.componentWillUnmount(); } catch (unmountError) { captureError(current, unmountError); @@ -495,6 +499,8 @@ module.exports = function( if (__DEV__) { startPhaseTimer(finishedWork, 'componentDidMount'); } + instance.props = finishedWork.memoizedProps; + instance.state = finishedWork.memoizedState; instance.componentDidMount(); if (__DEV__) { stopPhaseTimer(); @@ -505,6 +511,8 @@ module.exports = function( if (__DEV__) { startPhaseTimer(finishedWork, 'componentDidUpdate'); } + instance.props = finishedWork.memoizedProps; + instance.state = finishedWork.memoizedState; instance.componentDidUpdate(prevProps, prevState); if (__DEV__) { stopPhaseTimer(); diff --git a/src/renderers/shared/fiber/__tests__/ReactIncrementalErrorHandling-test.js b/src/renderers/shared/fiber/__tests__/ReactIncrementalErrorHandling-test.js index 95e862867033e..433d3d6bc3e6a 100644 --- a/src/renderers/shared/fiber/__tests__/ReactIncrementalErrorHandling-test.js +++ b/src/renderers/shared/fiber/__tests__/ReactIncrementalErrorHandling-test.js @@ -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(); + expect(ReactNoop.flush()).toEqual([ + 'render: 0', + 'render: 1', + 'componentWillUnmount: 0', + ]); + }); });