Skip to content

Commit 7f08e90

Browse files
author
Brian Vaughn
authored
Fix missing context to componentDidMount() when double-invoking lifecycles (#19935)
1 parent 9198a5c commit 7f08e90

File tree

2 files changed

+41
-13
lines changed

2 files changed

+41
-13
lines changed

packages/react-reconciler/src/ReactFiberCommitWork.new.js

+2-13
Original file line numberDiff line numberDiff line change
@@ -2044,7 +2044,7 @@ function invokeLayoutEffectMountInDEV(fiber: Fiber): void {
20442044
}
20452045
case ClassComponent: {
20462046
const instance = fiber.stateNode;
2047-
invokeGuardedCallback(null, instance.componentDidMount, null);
2047+
invokeGuardedCallback(null, instance.componentDidMount, instance);
20482048
if (hasCaughtError()) {
20492049
const mountError = clearCaughtError();
20502050
captureCommitPhaseError(fiber, fiber.return, mountError);
@@ -2103,18 +2103,7 @@ function invokeLayoutEffectUnmountInDEV(fiber: Fiber): void {
21032103
case ClassComponent: {
21042104
const instance = fiber.stateNode;
21052105
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);
21182107
}
21192108
break;
21202109
}

packages/react-reconciler/src/__tests__/ReactDoubleInvokeEvents-test.internal.js

+39
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,45 @@ describe('ReactDoubleInvokeEvents', () => {
240240
expect(Scheduler).toHaveYielded([]);
241241
});
242242

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+
243282
it('double invoking works for class components', () => {
244283
class App extends React.PureComponent {
245284
componentDidMount() {

0 commit comments

Comments
 (0)