From 7f08e908b10a58cda902611378ec053003d371ed Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Wed, 30 Sep 2020 15:56:19 -0400 Subject: [PATCH] Fix missing context to componentDidMount() when double-invoking lifecycles (#19935) --- .../src/ReactFiberCommitWork.new.js | 15 +------ .../ReactDoubleInvokeEvents-test.internal.js | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.new.js b/packages/react-reconciler/src/ReactFiberCommitWork.new.js index d8843eb0ca0d..4e9acfae1135 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.new.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.new.js @@ -2044,7 +2044,7 @@ function invokeLayoutEffectMountInDEV(fiber: Fiber): void { } case ClassComponent: { const instance = fiber.stateNode; - invokeGuardedCallback(null, instance.componentDidMount, null); + invokeGuardedCallback(null, instance.componentDidMount, instance); if (hasCaughtError()) { const mountError = clearCaughtError(); captureCommitPhaseError(fiber, fiber.return, mountError); @@ -2103,18 +2103,7 @@ function invokeLayoutEffectUnmountInDEV(fiber: Fiber): void { case ClassComponent: { const instance = fiber.stateNode; if (typeof instance.componentWillUnmount === 'function') { - invokeGuardedCallback( - null, - safelyCallComponentWillUnmount, - null, - fiber, - instance, - fiber.return, - ); - if (hasCaughtError()) { - const unmountError = clearCaughtError(); - captureCommitPhaseError(fiber, fiber.return, unmountError); - } + safelyCallComponentWillUnmount(fiber, instance, fiber.return); } break; } diff --git a/packages/react-reconciler/src/__tests__/ReactDoubleInvokeEvents-test.internal.js b/packages/react-reconciler/src/__tests__/ReactDoubleInvokeEvents-test.internal.js index e6eaa8a9d615..fddc3744245a 100644 --- a/packages/react-reconciler/src/__tests__/ReactDoubleInvokeEvents-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactDoubleInvokeEvents-test.internal.js @@ -240,6 +240,45 @@ describe('ReactDoubleInvokeEvents', () => { expect(Scheduler).toHaveYielded([]); }); + it('passes the right context to class component lifecycles', () => { + class App extends React.PureComponent { + test() {} + + componentDidMount() { + this.test(); + Scheduler.unstable_yieldValue('componentDidMount'); + } + + componentDidUpdate() { + this.test(); + Scheduler.unstable_yieldValue('componentDidUpdate'); + } + + componentWillUnmount() { + this.test(); + Scheduler.unstable_yieldValue('componentWillUnmount'); + } + + render() { + return null; + } + } + + ReactNoop.act(() => { + ReactNoop.render(); + }); + + if (__DEV__ && __VARIANT__) { + expect(Scheduler).toHaveYielded([ + 'componentDidMount', + 'componentWillUnmount', + 'componentDidMount', + ]); + } else { + expect(Scheduler).toHaveYielded(['componentDidMount']); + } + }); + it('double invoking works for class components', () => { class App extends React.PureComponent { componentDidMount() {