Skip to content

Commit 57333ca

Browse files
gaearontrueadm
andauthored
Show first component stack in context warning (#17922)
* Update tests * Show first component stack in context warning Co-authored-by: Dominic Gannaway <[email protected]>
1 parent a8fce06 commit 57333ca

6 files changed

+45
-82
lines changed

packages/react-reconciler/src/ReactStrictModeWarnings.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,16 +324,19 @@ if (__DEV__) {
324324
ReactStrictModeWarnings.flushLegacyContextWarning = () => {
325325
((pendingLegacyContextWarning: any): FiberToFiberComponentsMap).forEach(
326326
(fiberArray: FiberArray, strictRoot) => {
327+
if (fiberArray.length === 0) {
328+
return;
329+
}
330+
const firstFiber = fiberArray[0];
331+
327332
const uniqueNames = new Set();
328333
fiberArray.forEach(fiber => {
329334
uniqueNames.add(getComponentName(fiber.type) || 'Component');
330335
didWarnAboutLegacyContext.add(fiber.type);
331336
});
332337

333338
const sortedNames = setToSortedString(uniqueNames);
334-
const strictRootComponentStack = getStackByFiberInDevAndProd(
335-
strictRoot,
336-
);
339+
const firstComponentStack = getStackByFiberInDevAndProd(firstFiber);
337340

338341
console.error(
339342
'Legacy context API has been detected within a strict-mode tree.' +
@@ -343,7 +346,7 @@ if (__DEV__) {
343346
'\n\nLearn more about this warning here: https://fb.me/react-legacy-context' +
344347
'%s',
345348
sortedNames,
346-
strictRootComponentStack,
349+
firstComponentStack,
347350
);
348351
},
349352
);

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

Lines changed: 24 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,7 +1917,6 @@ describe('ReactIncremental', () => {
19171917
'The old API will be supported in all 16.x releases, but applications ' +
19181918
'using it should migrate to the new version.\n\n' +
19191919
'Please update the following components: Intl, ShowBoth, ShowLocale',
1920-
{withoutStack: true},
19211920
);
19221921

19231922
ReactNoop.render(
@@ -1974,7 +1973,6 @@ describe('ReactIncremental', () => {
19741973
'The old API will be supported in all 16.x releases, but applications ' +
19751974
'using it should migrate to the new version.\n\n' +
19761975
'Please update the following components: Router, ShowRoute',
1977-
{withoutStack: true},
19781976
);
19791977
});
19801978

@@ -2000,14 +1998,11 @@ describe('ReactIncremental', () => {
20001998
}
20011999

20022000
ReactNoop.render(<Recurse />);
2003-
expect(() =>
2004-
expect(Scheduler).toFlushWithoutYielding(),
2005-
).toErrorDev(
2001+
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
20062002
'Legacy context API has been detected within a strict-mode tree.\n\n' +
20072003
'The old API will be supported in all 16.x releases, but applications ' +
20082004
'using it should migrate to the new version.\n\n' +
20092005
'Please update the following components: Recurse',
2010-
{withoutStack: true},
20112006
);
20122007
expect(ops).toEqual([
20132008
'Recurse {}',
@@ -2041,20 +2036,17 @@ describe('ReactIncremental', () => {
20412036
};
20422037

20432038
ReactNoop.render(<Recurse />);
2044-
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2045-
[
2046-
'Warning: The <Recurse /> component appears to be a function component that returns a class instance. ' +
2047-
'Change Recurse to a class that extends React.Component instead. ' +
2048-
"If you can't use a class try assigning the prototype on the function as a workaround. " +
2049-
'`Recurse.prototype = React.Component.prototype`. ' +
2050-
"Don't use an arrow function since it cannot be called with `new` by React.",
2051-
'Legacy context API has been detected within a strict-mode tree.\n\n' +
2052-
'The old API will be supported in all 16.x releases, but applications ' +
2053-
'using it should migrate to the new version.\n\n' +
2054-
'Please update the following components: Recurse',
2055-
],
2056-
{withoutStack: 1},
2057-
);
2039+
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev([
2040+
'Warning: The <Recurse /> component appears to be a function component that returns a class instance. ' +
2041+
'Change Recurse to a class that extends React.Component instead. ' +
2042+
"If you can't use a class try assigning the prototype on the function as a workaround. " +
2043+
'`Recurse.prototype = React.Component.prototype`. ' +
2044+
"Don't use an arrow function since it cannot be called with `new` by React.",
2045+
'Legacy context API has been detected within a strict-mode tree.\n\n' +
2046+
'The old API will be supported in all 16.x releases, but applications ' +
2047+
'using it should migrate to the new version.\n\n' +
2048+
'Please update the following components: Recurse',
2049+
]);
20582050
expect(ops).toEqual([
20592051
'Recurse {}',
20602052
'Recurse {"n":2}',
@@ -2120,7 +2112,6 @@ describe('ReactIncremental', () => {
21202112
'The old API will be supported in all 16.x releases, but applications ' +
21212113
'using it should migrate to the new version.\n\n' +
21222114
'Please update the following components: Intl, ShowLocale',
2123-
{withoutStack: true},
21242115
);
21252116
});
21262117

@@ -2196,14 +2187,11 @@ describe('ReactIncremental', () => {
21962187
</IndirectionFn>
21972188
</Intl>,
21982189
);
2199-
expect(() =>
2200-
expect(Scheduler).toFlushWithoutYielding(),
2201-
).toErrorDev(
2190+
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
22022191
'Legacy context API has been detected within a strict-mode tree.\n\n' +
22032192
'The old API will be supported in all 16.x releases, but applications ' +
22042193
'using it should migrate to the new version.\n\n' +
22052194
'Please update the following components: Intl, ShowLocaleClass, ShowLocaleFn',
2206-
{withoutStack: true},
22072195
);
22082196
expect(ops).toEqual([
22092197
'Intl:read {}',
@@ -2292,14 +2280,11 @@ describe('ReactIncremental', () => {
22922280
</IndirectionFn>
22932281
</Stateful>,
22942282
);
2295-
expect(() =>
2296-
expect(Scheduler).toFlushWithoutYielding(),
2297-
).toErrorDev(
2283+
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
22982284
'Legacy context API has been detected within a strict-mode tree.\n\n' +
22992285
'The old API will be supported in all 16.x releases, but applications ' +
23002286
'using it should migrate to the new version.\n\n' +
23012287
'Please update the following components: Intl, ShowLocaleClass, ShowLocaleFn',
2302-
{withoutStack: true},
23032288
);
23042289
expect(ops).toEqual([
23052290
'Intl:read {}',
@@ -2365,14 +2350,11 @@ describe('ReactIncremental', () => {
23652350

23662351
// Init
23672352
ReactNoop.render(<Root />);
2368-
expect(() =>
2369-
expect(Scheduler).toFlushWithoutYielding(),
2370-
).toErrorDev(
2353+
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
23712354
'Legacy context API has been detected within a strict-mode tree.\n\n' +
23722355
'The old API will be supported in all 16.x releases, but applications ' +
23732356
'using it should migrate to the new version.\n\n' +
23742357
'Please update the following components: Child',
2375-
{withoutStack: true},
23762358
);
23772359

23782360
// Trigger an update in the middle of the tree
@@ -2419,14 +2401,11 @@ describe('ReactIncremental', () => {
24192401

24202402
// Init
24212403
ReactNoop.render(<Root />);
2422-
expect(() =>
2423-
expect(Scheduler).toFlushWithoutYielding(),
2424-
).toErrorDev(
2404+
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
24252405
'Legacy context API has been detected within a strict-mode tree.\n\n' +
24262406
'The old API will be supported in all 16.x releases, but applications ' +
24272407
'using it should migrate to the new version.\n\n' +
24282408
'Please update the following components: ContextProvider',
2429-
{withoutStack: true},
24302409
);
24312410

24322411
// Trigger an update in the middle of the tree
@@ -2479,7 +2458,7 @@ describe('ReactIncremental', () => {
24792458
'using it should migrate to the new version.\n\n' +
24802459
'Please update the following components: MyComponent',
24812460
],
2482-
{withoutStack: true},
2461+
{withoutStack: 1},
24832462
);
24842463

24852464
expect(ops).toEqual([
@@ -2622,14 +2601,11 @@ describe('ReactIncremental', () => {
26222601
</TopContextProvider>,
26232602
);
26242603

2625-
expect(() =>
2626-
expect(Scheduler).toFlushWithoutYielding(),
2627-
).toErrorDev(
2604+
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
26282605
'Legacy context API has been detected within a strict-mode tree.\n\n' +
26292606
'The old API will be supported in all 16.x releases, but applications ' +
26302607
'using it should migrate to the new version.\n\n' +
26312608
'Please update the following components: Child, TopContextProvider',
2632-
{withoutStack: true},
26332609
);
26342610
expect(rendered).toEqual(['count:0']);
26352611
instance.updateCount();
@@ -2688,14 +2664,11 @@ describe('ReactIncremental', () => {
26882664
</TopContextProvider>,
26892665
);
26902666

2691-
expect(() =>
2692-
expect(Scheduler).toFlushWithoutYielding(),
2693-
).toErrorDev(
2667+
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
26942668
'Legacy context API has been detected within a strict-mode tree.\n\n' +
26952669
'The old API will be supported in all 16.x releases, but applications ' +
26962670
'using it should migrate to the new version.\n\n' +
26972671
'Please update the following components: Child, MiddleContextProvider, TopContextProvider',
2698-
{withoutStack: true},
26992672
);
27002673
expect(rendered).toEqual(['count:0']);
27012674
instance.updateCount();
@@ -2763,14 +2736,11 @@ describe('ReactIncremental', () => {
27632736
</TopContextProvider>,
27642737
);
27652738

2766-
expect(() =>
2767-
expect(Scheduler).toFlushWithoutYielding(),
2768-
).toErrorDev(
2739+
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
27692740
'Legacy context API has been detected within a strict-mode tree.\n\n' +
27702741
'The old API will be supported in all 16.x releases, but applications ' +
27712742
'using it should migrate to the new version.\n\n' +
27722743
'Please update the following components: Child, MiddleContextProvider, TopContextProvider',
2773-
{withoutStack: true},
27742744
);
27752745
expect(rendered).toEqual(['count:0']);
27762746
instance.updateCount();
@@ -2848,14 +2818,11 @@ describe('ReactIncremental', () => {
28482818
</TopContextProvider>,
28492819
);
28502820

2851-
expect(() =>
2852-
expect(Scheduler).toFlushWithoutYielding(),
2853-
).toErrorDev(
2821+
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
28542822
'Legacy context API has been detected within a strict-mode tree.\n\n' +
28552823
'The old API will be supported in all 16.x releases, but applications ' +
28562824
'using it should migrate to the new version.\n\n' +
28572825
'Please update the following components: Child, MiddleContextProvider, TopContextProvider',
2858-
{withoutStack: true},
28592826
);
28602827
expect(rendered).toEqual(['count:0, name:brian']);
28612828
topInstance.updateCount();
@@ -2956,10 +2923,9 @@ describe('ReactIncremental', () => {
29562923
ReactNoop.render(<Boundary />);
29572924
expect(() => {
29582925
expect(Scheduler).toFlushWithoutYielding();
2959-
}).toErrorDev(
2960-
['Legacy context API has been detected within a strict-mode tree'],
2961-
{withoutStack: true},
2962-
);
2926+
}).toErrorDev([
2927+
'Legacy context API has been detected within a strict-mode tree',
2928+
]);
29632929
}
29642930

29652931
// First, verify that this code path normally receives Fibers as keys,

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

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,14 +1148,11 @@ describe('ReactIncrementalErrorHandling', () => {
11481148
<Connector />
11491149
</Provider>,
11501150
);
1151-
expect(() =>
1152-
expect(Scheduler).toFlushWithoutYielding(),
1153-
).toErrorDev(
1151+
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
11541152
'Legacy context API has been detected within a strict-mode tree.\n\n' +
11551153
'The old API will be supported in all 16.x releases, but ' +
11561154
'applications using it should migrate to the new version.\n\n' +
11571155
'Please update the following components: Connector, Provider',
1158-
{withoutStack: true},
11591156
);
11601157

11611158
// If the context stack does not unwind, span will get 'abcde'
@@ -1649,19 +1646,16 @@ describe('ReactIncrementalErrorHandling', () => {
16491646
ReactNoop.render(<Provider />);
16501647
expect(() => {
16511648
expect(Scheduler).toFlushAndThrow('Oops!');
1652-
}).toErrorDev(
1653-
[
1654-
'Warning: The <Provider /> component appears to be a function component that returns a class instance. ' +
1655-
'Change Provider to a class that extends React.Component instead. ' +
1656-
"If you can't use a class try assigning the prototype on the function as a workaround. " +
1657-
'`Provider.prototype = React.Component.prototype`. ' +
1658-
"Don't use an arrow function since it cannot be called with `new` by React.",
1659-
'Legacy context API has been detected within a strict-mode tree.\n\n' +
1660-
'The old API will be supported in all 16.x releases, but ' +
1661-
'applications using it should migrate to the new version.\n\n' +
1662-
'Please update the following components: Provider',
1663-
],
1664-
{withoutStack: 1},
1665-
);
1649+
}).toErrorDev([
1650+
'Warning: The <Provider /> component appears to be a function component that returns a class instance. ' +
1651+
'Change Provider to a class that extends React.Component instead. ' +
1652+
"If you can't use a class try assigning the prototype on the function as a workaround. " +
1653+
'`Provider.prototype = React.Component.prototype`. ' +
1654+
"Don't use an arrow function since it cannot be called with `new` by React.",
1655+
'Legacy context API has been detected within a strict-mode tree.\n\n' +
1656+
'The old API will be supported in all 16.x releases, but ' +
1657+
'applications using it should migrate to the new version.\n\n' +
1658+
'Please update the following components: Provider',
1659+
]);
16661660
});
16671661
});

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ describe('ReactDebugFiberPerf', () => {
371371
'Using UNSAFE_componentWillUpdate in strict mode is not recommended',
372372
'Legacy context API has been detected within a strict-mode tree',
373373
],
374-
{withoutStack: true},
374+
{withoutStack: 3},
375375
);
376376
ReactNoop.render(<AllLifecycles />);
377377
addComment('Update');

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1198,7 +1198,6 @@ describe('ReactNewContext', () => {
11981198
'The old API will be supported in all 16.x releases, but applications ' +
11991199
'using it should migrate to the new version.\n\n' +
12001200
'Please update the following components: LegacyProvider',
1201-
{withoutStack: true},
12021201
);
12031202
expect(ReactNoop.getChildren()).toEqual([span('Child')]);
12041203

packages/react/src/__tests__/ReactStrictMode-test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ describe('context legacy', () => {
878878
'FunctionalLegacyContextConsumer, LegacyContextConsumer, LegacyContextProvider' +
879879
'\n\nLearn more about this warning here: ' +
880880
'https://fb.me/react-legacy-context' +
881+
'\n in LegacyContextProvider (at **)' +
881882
'\n in StrictMode (at **)' +
882883
'\n in div (at **)' +
883884
'\n in Root (at **)',

0 commit comments

Comments
 (0)