@samitouri / QOS-React-2 / commits / 57333ca33a

Show first component stack in context warning (#17922)

* Update tests * Show first component stack in context warning Co-authored-by: Dominic Gannaway <trueadm@users.noreply.github.com>

Dan Abramov committed Jan 29, 2020 at 14:57 UTC 57333ca33a0619ff2334e4eb19139b4c7e9830f7
6 files changed +45 -82
packages/react-reconciler/src/ReactStrictModeWarnings.js
+7 -4
@@ -324,6 +324,11 @@ if (__DEV__) {
324 ReactStrictModeWarnings.flushLegacyContextWarning = () => {
325 ((pendingLegacyContextWarning: any): FiberToFiberComponentsMap).forEach(
326 (fiberArray: FiberArray, strictRoot) => {
327 + if (fiberArray.length === 0) {
328 + return;
329 + }
330 + const firstFiber = fiberArray[0];
331 +
332 const uniqueNames = new Set();
333 fiberArray.forEach(fiber => {
334 uniqueNames.add(getComponentName(fiber.type) || 'Component');
@@ -331,9 +336,7 @@ if (__DEV__) {
336 });
337
338 const sortedNames = setToSortedString(uniqueNames);
334 - const strictRootComponentStack = getStackByFiberInDevAndProd(
335 - strictRoot,
336 - );
339 + const firstComponentStack = getStackByFiberInDevAndProd(firstFiber);
340
341 console.error(
342 'Legacy context API has been detected within a strict-mode tree.' +
@@ -343,7 +346,7 @@ if (__DEV__) {
346 '\n\nLearn more about this warning here: https://fb.me/react-legacy-context' +
347 '%s',
348 sortedNames,
346 - strictRootComponentStack,
349 + firstComponentStack,
350 );
351 },
352 );
packages/react-reconciler/src/__tests__/ReactIncremental-test.internal.js
+24 -58
@@ -1917,7 +1917,6 @@ describe('ReactIncremental', () => {
1917 'The old API will be supported in all 16.x releases, but applications ' +
1918 'using it should migrate to the new version.\n\n' +
1919 'Please update the following components: Intl, ShowBoth, ShowLocale',
1920 - {withoutStack: true},
1920 );
1921
1922 ReactNoop.render(
@@ -1974,7 +1973,6 @@ describe('ReactIncremental', () => {
1973 'The old API will be supported in all 16.x releases, but applications ' +
1974 'using it should migrate to the new version.\n\n' +
1975 'Please update the following components: Router, ShowRoute',
1977 - {withoutStack: true},
1976 );
1977 });
1978
@@ -2000,14 +1998,11 @@ describe('ReactIncremental', () => {
1998 }
1999
2000 ReactNoop.render(<Recurse />);
2003 - expect(() =>
2004 - expect(Scheduler).toFlushWithoutYielding(),
2005 - ).toErrorDev(
2001 + expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2002 'Legacy context API has been detected within a strict-mode tree.\n\n' +
2003 'The old API will be supported in all 16.x releases, but applications ' +
2004 'using it should migrate to the new version.\n\n' +
2005 'Please update the following components: Recurse',
2010 - {withoutStack: true},
2006 );
2007 expect(ops).toEqual([
2008 'Recurse {}',
@@ -2041,20 +2036,17 @@ describe('ReactIncremental', () => {
2036 };
2037
2038 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 + ]);
2050 expect(ops).toEqual([
2051 'Recurse {}',
2052 'Recurse {"n":2}',
@@ -2120,7 +2112,6 @@ describe('ReactIncremental', () => {
2112 'The old API will be supported in all 16.x releases, but applications ' +
2113 'using it should migrate to the new version.\n\n' +
2114 'Please update the following components: Intl, ShowLocale',
2123 - {withoutStack: true},
2115 );
2116 });
2117
@@ -2196,14 +2187,11 @@ describe('ReactIncremental', () => {
2187 </IndirectionFn>
2188 </Intl>,
2189 );
2199 - expect(() =>
2200 - expect(Scheduler).toFlushWithoutYielding(),
2201 - ).toErrorDev(
2190 + expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2191 'Legacy context API has been detected within a strict-mode tree.\n\n' +
2192 'The old API will be supported in all 16.x releases, but applications ' +
2193 'using it should migrate to the new version.\n\n' +
2194 'Please update the following components: Intl, ShowLocaleClass, ShowLocaleFn',
2206 - {withoutStack: true},
2195 );
2196 expect(ops).toEqual([
2197 'Intl:read {}',
@@ -2292,14 +2280,11 @@ describe('ReactIncremental', () => {
2280 </IndirectionFn>
2281 </Stateful>,
2282 );
2295 - expect(() =>
2296 - expect(Scheduler).toFlushWithoutYielding(),
2297 - ).toErrorDev(
2283 + expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2284 'Legacy context API has been detected within a strict-mode tree.\n\n' +
2285 'The old API will be supported in all 16.x releases, but applications ' +
2286 'using it should migrate to the new version.\n\n' +
2287 'Please update the following components: Intl, ShowLocaleClass, ShowLocaleFn',
2302 - {withoutStack: true},
2288 );
2289 expect(ops).toEqual([
2290 'Intl:read {}',
@@ -2365,14 +2350,11 @@ describe('ReactIncremental', () => {
2350
2351 // Init
2352 ReactNoop.render(<Root />);
2368 - expect(() =>
2369 - expect(Scheduler).toFlushWithoutYielding(),
2370 - ).toErrorDev(
2353 + expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2354 'Legacy context API has been detected within a strict-mode tree.\n\n' +
2355 'The old API will be supported in all 16.x releases, but applications ' +
2356 'using it should migrate to the new version.\n\n' +
2357 'Please update the following components: Child',
2375 - {withoutStack: true},
2358 );
2359
2360 // Trigger an update in the middle of the tree
@@ -2419,14 +2401,11 @@ describe('ReactIncremental', () => {
2401
2402 // Init
2403 ReactNoop.render(<Root />);
2422 - expect(() =>
2423 - expect(Scheduler).toFlushWithoutYielding(),
2424 - ).toErrorDev(
2404 + expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2405 'Legacy context API has been detected within a strict-mode tree.\n\n' +
2406 'The old API will be supported in all 16.x releases, but applications ' +
2407 'using it should migrate to the new version.\n\n' +
2408 'Please update the following components: ContextProvider',
2429 - {withoutStack: true},
2409 );
2410
2411 // Trigger an update in the middle of the tree
@@ -2479,7 +2458,7 @@ describe('ReactIncremental', () => {
2458 'using it should migrate to the new version.\n\n' +
2459 'Please update the following components: MyComponent',
2460 ],
2482 - {withoutStack: true},
2461 + {withoutStack: 1},
2462 );
2463
2464 expect(ops).toEqual([
@@ -2622,14 +2601,11 @@ describe('ReactIncremental', () => {
2601 </TopContextProvider>,
2602 );
2603
2625 - expect(() =>
2626 - expect(Scheduler).toFlushWithoutYielding(),
2627 - ).toErrorDev(
2604 + expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2605 'Legacy context API has been detected within a strict-mode tree.\n\n' +
2606 'The old API will be supported in all 16.x releases, but applications ' +
2607 'using it should migrate to the new version.\n\n' +
2608 'Please update the following components: Child, TopContextProvider',
2632 - {withoutStack: true},
2609 );
2610 expect(rendered).toEqual(['count:0']);
2611 instance.updateCount();
@@ -2688,14 +2664,11 @@ describe('ReactIncremental', () => {
2664 </TopContextProvider>,
2665 );
2666
2691 - expect(() =>
2692 - expect(Scheduler).toFlushWithoutYielding(),
2693 - ).toErrorDev(
2667 + expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2668 'Legacy context API has been detected within a strict-mode tree.\n\n' +
2669 'The old API will be supported in all 16.x releases, but applications ' +
2670 'using it should migrate to the new version.\n\n' +
2671 'Please update the following components: Child, MiddleContextProvider, TopContextProvider',
2698 - {withoutStack: true},
2672 );
2673 expect(rendered).toEqual(['count:0']);
2674 instance.updateCount();
@@ -2763,14 +2736,11 @@ describe('ReactIncremental', () => {
2736 </TopContextProvider>,
2737 );
2738
2766 - expect(() =>
2767 - expect(Scheduler).toFlushWithoutYielding(),
2768 - ).toErrorDev(
2739 + expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2740 'Legacy context API has been detected within a strict-mode tree.\n\n' +
2741 'The old API will be supported in all 16.x releases, but applications ' +
2742 'using it should migrate to the new version.\n\n' +
2743 'Please update the following components: Child, MiddleContextProvider, TopContextProvider',
2773 - {withoutStack: true},
2744 );
2745 expect(rendered).toEqual(['count:0']);
2746 instance.updateCount();
@@ -2848,14 +2818,11 @@ describe('ReactIncremental', () => {
2818 </TopContextProvider>,
2819 );
2820
2851 - expect(() =>
2852 - expect(Scheduler).toFlushWithoutYielding(),
2853 - ).toErrorDev(
2821 + expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2822 'Legacy context API has been detected within a strict-mode tree.\n\n' +
2823 'The old API will be supported in all 16.x releases, but applications ' +
2824 'using it should migrate to the new version.\n\n' +
2825 'Please update the following components: Child, MiddleContextProvider, TopContextProvider',
2858 - {withoutStack: true},
2826 );
2827 expect(rendered).toEqual(['count:0, name:brian']);
2828 topInstance.updateCount();
@@ -2956,10 +2923,9 @@ describe('ReactIncremental', () => {
2923 ReactNoop.render(<Boundary />);
2924 expect(() => {
2925 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 + ]);
2929 }
2930
2931 // First, verify that this code path normally receives Fibers as keys,
packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
+12 -18
@@ -1148,14 +1148,11 @@ describe('ReactIncrementalErrorHandling', () => {
1148 <Connector />
1149 </Provider>,
1150 );
1151 - expect(() =>
1152 - expect(Scheduler).toFlushWithoutYielding(),
1153 - ).toErrorDev(
1151 + expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
1152 'Legacy context API has been detected within a strict-mode tree.\n\n' +
1153 'The old API will be supported in all 16.x releases, but ' +
1154 'applications using it should migrate to the new version.\n\n' +
1155 'Please update the following components: Connector, Provider',
1158 - {withoutStack: true},
1156 );
1157
1158 // If the context stack does not unwind, span will get 'abcde'
@@ -1649,19 +1646,16 @@ describe('ReactIncrementalErrorHandling', () => {
1646 ReactNoop.render(<Provider />);
1647 expect(() => {
1648 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 + ]);
1660 });
1661 });
packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js
+1 -1
@@ -371,7 +371,7 @@ describe('ReactDebugFiberPerf', () => {
371 'Using UNSAFE_componentWillUpdate in strict mode is not recommended',
372 'Legacy context API has been detected within a strict-mode tree',
373 ],
374 - {withoutStack: true},
374 + {withoutStack: 3},
375 );
376 ReactNoop.render(<AllLifecycles />);
377 addComment('Update');
packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js
-1
@@ -1198,7 +1198,6 @@ describe('ReactNewContext', () => {
1198 'The old API will be supported in all 16.x releases, but applications ' +
1199 'using it should migrate to the new version.\n\n' +
1200 'Please update the following components: LegacyProvider',
1201 - {withoutStack: true},
1201 );
1202 expect(ReactNoop.getChildren()).toEqual([span('Child')]);
1203
packages/react/src/__tests__/ReactStrictMode-test.js
+1
@@ -878,6 +878,7 @@ describe('context legacy', () => {
878 'FunctionalLegacyContextConsumer, LegacyContextConsumer, LegacyContextProvider' +
879 '\n\nLearn more about this warning here: ' +
880 'https://fb.me/react-legacy-context' +
881 + '\n in LegacyContextProvider (at **)' +
882 '\n in StrictMode (at **)' +
883 '\n in div (at **)' +
884 '\n in Root (at **)',