Skip to content

Commit a1b5f0f

Browse files
committed
Improved flushing of pending warnings to avoid leaks
1 parent d90987f commit a1b5f0f

File tree

4 files changed

+22
-24
lines changed

4 files changed

+22
-24
lines changed

packages/react-reconciler/src/ReactDebugAsyncWarnings.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ type FiberToLifecycleMap = Map<Fiber, LifecycleToComponentsMap>;
2424
const DID_WARN_KEY = '__didWarnAboutUnsafeAsyncLifecycles';
2525

2626
const ReactDebugAsyncWarnings = {
27-
flushPendingAsyncWarnings(maybeAsyncRoot: Fiber): void {},
27+
discardPendingWarnings(): void {},
28+
flushPendingAsyncWarnings(): void {},
2829
recordLifecycleWarnings(fiber: Fiber, instance: any): void {},
2930
};
3031

@@ -37,15 +38,13 @@ if (__DEV__) {
3738

3839
let pendingWarningsMap: FiberToLifecycleMap = new Map();
3940

40-
ReactDebugAsyncWarnings.flushPendingAsyncWarnings = (
41-
maybeAsyncRoot: Fiber,
42-
) => {
41+
ReactDebugAsyncWarnings.discardPendingWarnings = () => {
42+
pendingWarningsMap = new Map();
43+
};
44+
45+
ReactDebugAsyncWarnings.flushPendingAsyncWarnings = () => {
4346
((pendingWarningsMap: any): FiberToLifecycleMap).forEach(
4447
(lifecycleWarningsMap, asyncRoot) => {
45-
if (asyncRoot !== maybeAsyncRoot) {
46-
return;
47-
}
48-
4948
const lifecyclesWarningMesages = [];
5049

5150
Object.keys(lifecycleWarningsMap).forEach(lifecycle => {
@@ -85,10 +84,10 @@ if (__DEV__) {
8584
lifecyclesWarningMesages.join('\n\n'),
8685
);
8786
}
88-
89-
pendingWarningsMap.delete(asyncRoot);
9087
},
9188
);
89+
90+
pendingWarningsMap = new Map();
9291
};
9392

9493
const getAsyncRoot = (fiber: Fiber): Fiber => {

packages/react-reconciler/src/ReactFiberScheduler.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,10 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
311311
}
312312

313313
function commitAllLifeCycles() {
314+
if (__DEV__) {
315+
ReactDebugAsyncWarnings.flushPendingAsyncWarnings();
316+
}
317+
314318
while (nextEffect !== null) {
315319
const effectTag = nextEffect.effectTag;
316320

@@ -544,7 +548,6 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
544548
);
545549
if (__DEV__) {
546550
ReactDebugCurrentFiber.resetCurrentFiber();
547-
ReactDebugAsyncWarnings.flushPendingAsyncWarnings(workInProgress);
548551
}
549552

550553
const returnFiber = workInProgress.return;
@@ -653,6 +656,10 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
653656
}
654657

655658
function performFailedUnitOfWork(workInProgress: Fiber): Fiber | null {
659+
if (__DEV__) {
660+
ReactDebugAsyncWarnings.discardPendingWarnings();
661+
}
662+
656663
// The current, flushed, state of this fiber is the alternate.
657664
// Ideally nothing should rely on this, but relying on it here
658665
// means that we don't need an additional field on the work in

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,13 @@ describe('ReactIncrementalErrorLogging', () => {
4848
);
4949

5050
expect(() => {
51-
expect(ReactNoop.flushDeferredPri).toWarnDev([
52-
'componentWillMount: Please update the following components ' +
53-
'to use componentDidMount instead: ErrorThrowingComponent',
51+
expect(ReactNoop.flushDeferredPri).toWarnDev(
5452
'The above error occurred in the <ErrorThrowingComponent> component:\n' +
5553
' in ErrorThrowingComponent (at **)\n' +
5654
' in span (at **)\n' +
5755
' in div (at **)\n\n' +
5856
'Consider adding an error boundary to your tree to customize error handling behavior.',
59-
]);
57+
);
6058
}).toThrowError('componentWillMount error');
6159
});
6260

packages/react/src/__tests__/ReactAsyncClassComponent-test.internal.js

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ describe('ReactAsyncClassComponent', () => {
373373
rendered.update(<AsyncRoot foo={false} />);
374374
});
375375

376-
it('should warn about lifecycles even in the event of an error', () => {
376+
it('should not warn about uncommitted lifecycles in the event of an error', () => {
377377
let caughtError;
378378

379379
class AsyncRoot extends React.unstable_AsyncComponent {
@@ -408,20 +408,14 @@ describe('ReactAsyncClassComponent', () => {
408408

409409
expect(() => {
410410
ReactTestRenderer.create(<AsyncRoot foo={true} />);
411-
}).toWarnDev([
412-
'Unsafe lifecycle methods were found within the following async tree:' +
413-
'\n in AsyncRoot (at **)' +
414-
'\n\ncomponentWillMount: Please update the following components ' +
415-
'to use componentDidMount instead: Foo' +
416-
'\n\nLearn more about this warning here:' +
417-
'\nhttps://fb.me/react-async-component-lifecycle-hooks',
411+
}).toWarnDev(
418412
'Unsafe lifecycle methods were found within the following async tree:' +
419413
'\n in AsyncRoot (at **)' +
420414
'\n\ncomponentWillMount: Please update the following components ' +
421415
'to use componentDidMount instead: Bar' +
422416
'\n\nLearn more about this warning here:' +
423417
'\nhttps://fb.me/react-async-component-lifecycle-hooks',
424-
]);
418+
);
425419

426420
expect(caughtError).not.toBe(null);
427421
});

0 commit comments

Comments
 (0)