mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
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>
This commit is contained in:
co-authored by
Dominic Gannaway
parent
a8fce06d3e
commit
57333ca33a
@@ -324,6 +324,11 @@ if (__DEV__) {
|
||||
ReactStrictModeWarnings.flushLegacyContextWarning = () => {
|
||||
((pendingLegacyContextWarning: any): FiberToFiberComponentsMap).forEach(
|
||||
(fiberArray: FiberArray, strictRoot) => {
|
||||
if (fiberArray.length === 0) {
|
||||
return;
|
||||
}
|
||||
const firstFiber = fiberArray[0];
|
||||
|
||||
const uniqueNames = new Set();
|
||||
fiberArray.forEach(fiber => {
|
||||
uniqueNames.add(getComponentName(fiber.type) || 'Component');
|
||||
@@ -331,9 +336,7 @@ if (__DEV__) {
|
||||
});
|
||||
|
||||
const sortedNames = setToSortedString(uniqueNames);
|
||||
const strictRootComponentStack = getStackByFiberInDevAndProd(
|
||||
strictRoot,
|
||||
);
|
||||
const firstComponentStack = getStackByFiberInDevAndProd(firstFiber);
|
||||
|
||||
console.error(
|
||||
'Legacy context API has been detected within a strict-mode tree.' +
|
||||
@@ -343,7 +346,7 @@ if (__DEV__) {
|
||||
'\n\nLearn more about this warning here: https://fb.me/react-legacy-context' +
|
||||
'%s',
|
||||
sortedNames,
|
||||
strictRootComponentStack,
|
||||
firstComponentStack,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1917,7 +1917,6 @@ describe('ReactIncremental', () => {
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Intl, ShowBoth, ShowLocale',
|
||||
{withoutStack: true},
|
||||
);
|
||||
|
||||
ReactNoop.render(
|
||||
@@ -1974,7 +1973,6 @@ describe('ReactIncremental', () => {
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Router, ShowRoute',
|
||||
{withoutStack: true},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -2000,14 +1998,11 @@ describe('ReactIncremental', () => {
|
||||
}
|
||||
|
||||
ReactNoop.render(<Recurse />);
|
||||
expect(() =>
|
||||
expect(Scheduler).toFlushWithoutYielding(),
|
||||
).toErrorDev(
|
||||
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Recurse',
|
||||
{withoutStack: true},
|
||||
);
|
||||
expect(ops).toEqual([
|
||||
'Recurse {}',
|
||||
@@ -2041,20 +2036,17 @@ describe('ReactIncremental', () => {
|
||||
};
|
||||
|
||||
ReactNoop.render(<Recurse />);
|
||||
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
|
||||
[
|
||||
'Warning: The <Recurse /> component appears to be a function component that returns a class instance. ' +
|
||||
'Change Recurse to a class that extends React.Component instead. ' +
|
||||
"If you can't use a class try assigning the prototype on the function as a workaround. " +
|
||||
'`Recurse.prototype = React.Component.prototype`. ' +
|
||||
"Don't use an arrow function since it cannot be called with `new` by React.",
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Recurse',
|
||||
],
|
||||
{withoutStack: 1},
|
||||
);
|
||||
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev([
|
||||
'Warning: The <Recurse /> component appears to be a function component that returns a class instance. ' +
|
||||
'Change Recurse to a class that extends React.Component instead. ' +
|
||||
"If you can't use a class try assigning the prototype on the function as a workaround. " +
|
||||
'`Recurse.prototype = React.Component.prototype`. ' +
|
||||
"Don't use an arrow function since it cannot be called with `new` by React.",
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Recurse',
|
||||
]);
|
||||
expect(ops).toEqual([
|
||||
'Recurse {}',
|
||||
'Recurse {"n":2}',
|
||||
@@ -2120,7 +2112,6 @@ describe('ReactIncremental', () => {
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Intl, ShowLocale',
|
||||
{withoutStack: true},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -2196,14 +2187,11 @@ describe('ReactIncremental', () => {
|
||||
</IndirectionFn>
|
||||
</Intl>,
|
||||
);
|
||||
expect(() =>
|
||||
expect(Scheduler).toFlushWithoutYielding(),
|
||||
).toErrorDev(
|
||||
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Intl, ShowLocaleClass, ShowLocaleFn',
|
||||
{withoutStack: true},
|
||||
);
|
||||
expect(ops).toEqual([
|
||||
'Intl:read {}',
|
||||
@@ -2292,14 +2280,11 @@ describe('ReactIncremental', () => {
|
||||
</IndirectionFn>
|
||||
</Stateful>,
|
||||
);
|
||||
expect(() =>
|
||||
expect(Scheduler).toFlushWithoutYielding(),
|
||||
).toErrorDev(
|
||||
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Intl, ShowLocaleClass, ShowLocaleFn',
|
||||
{withoutStack: true},
|
||||
);
|
||||
expect(ops).toEqual([
|
||||
'Intl:read {}',
|
||||
@@ -2365,14 +2350,11 @@ describe('ReactIncremental', () => {
|
||||
|
||||
// Init
|
||||
ReactNoop.render(<Root />);
|
||||
expect(() =>
|
||||
expect(Scheduler).toFlushWithoutYielding(),
|
||||
).toErrorDev(
|
||||
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Child',
|
||||
{withoutStack: true},
|
||||
);
|
||||
|
||||
// Trigger an update in the middle of the tree
|
||||
@@ -2419,14 +2401,11 @@ describe('ReactIncremental', () => {
|
||||
|
||||
// Init
|
||||
ReactNoop.render(<Root />);
|
||||
expect(() =>
|
||||
expect(Scheduler).toFlushWithoutYielding(),
|
||||
).toErrorDev(
|
||||
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: ContextProvider',
|
||||
{withoutStack: true},
|
||||
);
|
||||
|
||||
// Trigger an update in the middle of the tree
|
||||
@@ -2479,7 +2458,7 @@ describe('ReactIncremental', () => {
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: MyComponent',
|
||||
],
|
||||
{withoutStack: true},
|
||||
{withoutStack: 1},
|
||||
);
|
||||
|
||||
expect(ops).toEqual([
|
||||
@@ -2622,14 +2601,11 @@ describe('ReactIncremental', () => {
|
||||
</TopContextProvider>,
|
||||
);
|
||||
|
||||
expect(() =>
|
||||
expect(Scheduler).toFlushWithoutYielding(),
|
||||
).toErrorDev(
|
||||
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Child, TopContextProvider',
|
||||
{withoutStack: true},
|
||||
);
|
||||
expect(rendered).toEqual(['count:0']);
|
||||
instance.updateCount();
|
||||
@@ -2688,14 +2664,11 @@ describe('ReactIncremental', () => {
|
||||
</TopContextProvider>,
|
||||
);
|
||||
|
||||
expect(() =>
|
||||
expect(Scheduler).toFlushWithoutYielding(),
|
||||
).toErrorDev(
|
||||
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Child, MiddleContextProvider, TopContextProvider',
|
||||
{withoutStack: true},
|
||||
);
|
||||
expect(rendered).toEqual(['count:0']);
|
||||
instance.updateCount();
|
||||
@@ -2763,14 +2736,11 @@ describe('ReactIncremental', () => {
|
||||
</TopContextProvider>,
|
||||
);
|
||||
|
||||
expect(() =>
|
||||
expect(Scheduler).toFlushWithoutYielding(),
|
||||
).toErrorDev(
|
||||
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Child, MiddleContextProvider, TopContextProvider',
|
||||
{withoutStack: true},
|
||||
);
|
||||
expect(rendered).toEqual(['count:0']);
|
||||
instance.updateCount();
|
||||
@@ -2848,14 +2818,11 @@ describe('ReactIncremental', () => {
|
||||
</TopContextProvider>,
|
||||
);
|
||||
|
||||
expect(() =>
|
||||
expect(Scheduler).toFlushWithoutYielding(),
|
||||
).toErrorDev(
|
||||
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Child, MiddleContextProvider, TopContextProvider',
|
||||
{withoutStack: true},
|
||||
);
|
||||
expect(rendered).toEqual(['count:0, name:brian']);
|
||||
topInstance.updateCount();
|
||||
@@ -2956,10 +2923,9 @@ describe('ReactIncremental', () => {
|
||||
ReactNoop.render(<Boundary />);
|
||||
expect(() => {
|
||||
expect(Scheduler).toFlushWithoutYielding();
|
||||
}).toErrorDev(
|
||||
['Legacy context API has been detected within a strict-mode tree'],
|
||||
{withoutStack: true},
|
||||
);
|
||||
}).toErrorDev([
|
||||
'Legacy context API has been detected within a strict-mode tree',
|
||||
]);
|
||||
}
|
||||
|
||||
// First, verify that this code path normally receives Fibers as keys,
|
||||
|
||||
+12
-18
@@ -1148,14 +1148,11 @@ describe('ReactIncrementalErrorHandling', () => {
|
||||
<Connector />
|
||||
</Provider>,
|
||||
);
|
||||
expect(() =>
|
||||
expect(Scheduler).toFlushWithoutYielding(),
|
||||
).toErrorDev(
|
||||
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but ' +
|
||||
'applications using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Connector, Provider',
|
||||
{withoutStack: true},
|
||||
);
|
||||
|
||||
// If the context stack does not unwind, span will get 'abcde'
|
||||
@@ -1649,19 +1646,16 @@ describe('ReactIncrementalErrorHandling', () => {
|
||||
ReactNoop.render(<Provider />);
|
||||
expect(() => {
|
||||
expect(Scheduler).toFlushAndThrow('Oops!');
|
||||
}).toErrorDev(
|
||||
[
|
||||
'Warning: The <Provider /> component appears to be a function component that returns a class instance. ' +
|
||||
'Change Provider to a class that extends React.Component instead. ' +
|
||||
"If you can't use a class try assigning the prototype on the function as a workaround. " +
|
||||
'`Provider.prototype = React.Component.prototype`. ' +
|
||||
"Don't use an arrow function since it cannot be called with `new` by React.",
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but ' +
|
||||
'applications using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Provider',
|
||||
],
|
||||
{withoutStack: 1},
|
||||
);
|
||||
}).toErrorDev([
|
||||
'Warning: The <Provider /> component appears to be a function component that returns a class instance. ' +
|
||||
'Change Provider to a class that extends React.Component instead. ' +
|
||||
"If you can't use a class try assigning the prototype on the function as a workaround. " +
|
||||
'`Provider.prototype = React.Component.prototype`. ' +
|
||||
"Don't use an arrow function since it cannot be called with `new` by React.",
|
||||
'Legacy context API has been detected within a strict-mode tree.\n\n' +
|
||||
'The old API will be supported in all 16.x releases, but ' +
|
||||
'applications using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: Provider',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -371,7 +371,7 @@ describe('ReactDebugFiberPerf', () => {
|
||||
'Using UNSAFE_componentWillUpdate in strict mode is not recommended',
|
||||
'Legacy context API has been detected within a strict-mode tree',
|
||||
],
|
||||
{withoutStack: true},
|
||||
{withoutStack: 3},
|
||||
);
|
||||
ReactNoop.render(<AllLifecycles />);
|
||||
addComment('Update');
|
||||
|
||||
@@ -1198,7 +1198,6 @@ describe('ReactNewContext', () => {
|
||||
'The old API will be supported in all 16.x releases, but applications ' +
|
||||
'using it should migrate to the new version.\n\n' +
|
||||
'Please update the following components: LegacyProvider',
|
||||
{withoutStack: true},
|
||||
);
|
||||
expect(ReactNoop.getChildren()).toEqual([span('Child')]);
|
||||
|
||||
|
||||
@@ -878,6 +878,7 @@ describe('context legacy', () => {
|
||||
'FunctionalLegacyContextConsumer, LegacyContextConsumer, LegacyContextProvider' +
|
||||
'\n\nLearn more about this warning here: ' +
|
||||
'https://fb.me/react-legacy-context' +
|
||||
'\n in LegacyContextProvider (at **)' +
|
||||
'\n in StrictMode (at **)' +
|
||||
'\n in div (at **)' +
|
||||
'\n in Root (at **)',
|
||||
|
||||
Reference in New Issue
Block a user