@samitouri / QOS-React-2 / commits / 7f08e908b1

Fix missing context to componentDidMount() when double-invoking lifecycles (#19935)

Brian Vaughn committed Sep 30, 2020 at 15:56 UTC 7f08e908b10a58cda902611378ec053003d371ed
2 files changed +41 -13
packages/react-reconciler/src/ReactFiberCommitWork.new.js
+2 -13
@@ -2044,7 +2044,7 @@ function invokeLayoutEffectMountInDEV(fiber: Fiber): void {
2044 }
2045 case ClassComponent: {
2046 const instance = fiber.stateNode;
2047 - invokeGuardedCallback(null, instance.componentDidMount, null);
2047 + invokeGuardedCallback(null, instance.componentDidMount, instance);
2048 if (hasCaughtError()) {
2049 const mountError = clearCaughtError();
2050 captureCommitPhaseError(fiber, fiber.return, mountError);
@@ -2103,18 +2103,7 @@ function invokeLayoutEffectUnmountInDEV(fiber: Fiber): void {
2103 case ClassComponent: {
2104 const instance = fiber.stateNode;
2105 if (typeof instance.componentWillUnmount === 'function') {
2106 - invokeGuardedCallback(
2107 - null,
2108 - safelyCallComponentWillUnmount,
2109 - null,
2110 - fiber,
2111 - instance,
2112 - fiber.return,
2113 - );
2114 - if (hasCaughtError()) {
2115 - const unmountError = clearCaughtError();
2116 - captureCommitPhaseError(fiber, fiber.return, unmountError);
2117 - }
2106 + safelyCallComponentWillUnmount(fiber, instance, fiber.return);
2107 }
2108 break;
2109 }
packages/react-reconciler/src/__tests__/ReactDoubleInvokeEvents-test.internal.js
+39
@@ -240,6 +240,45 @@ describe('ReactDoubleInvokeEvents', () => {
240 expect(Scheduler).toHaveYielded([]);
241 });
242
243 + it('passes the right context to class component lifecycles', () => {
244 + class App extends React.PureComponent {
245 + test() {}
246 +
247 + componentDidMount() {
248 + this.test();
249 + Scheduler.unstable_yieldValue('componentDidMount');
250 + }
251 +
252 + componentDidUpdate() {
253 + this.test();
254 + Scheduler.unstable_yieldValue('componentDidUpdate');
255 + }
256 +
257 + componentWillUnmount() {
258 + this.test();
259 + Scheduler.unstable_yieldValue('componentWillUnmount');
260 + }
261 +
262 + render() {
263 + return null;
264 + }
265 + }
266 +
267 + ReactNoop.act(() => {
268 + ReactNoop.render(<App />);
269 + });
270 +
271 + if (__DEV__ && __VARIANT__) {
272 + expect(Scheduler).toHaveYielded([
273 + 'componentDidMount',
274 + 'componentWillUnmount',
275 + 'componentDidMount',
276 + ]);
277 + } else {
278 + expect(Scheduler).toHaveYielded(['componentDidMount']);
279 + }
280 + });
281 +
282 it('double invoking works for class components', () => {
283 class App extends React.PureComponent {
284 componentDidMount() {