diff --git a/packages/react-reconciler/src/ReactStrictModeWarnings.js b/packages/react-reconciler/src/ReactStrictModeWarnings.js
index 29af663d90ec6..a61185d8bf5fd 100644
--- a/packages/react-reconciler/src/ReactStrictModeWarnings.js
+++ b/packages/react-reconciler/src/ReactStrictModeWarnings.js
@@ -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,
);
},
);
diff --git a/packages/react-reconciler/src/__tests__/ReactIncremental-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncremental-test.internal.js
index e39b055f79c5f..a5e1a0ace5d20 100644
--- a/packages/react-reconciler/src/__tests__/ReactIncremental-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactIncremental-test.internal.js
@@ -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();
- 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();
- expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
- [
- 'Warning: The 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 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', () => {
,
);
- 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', () => {
,
);
- 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();
- 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();
- 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', () => {
,
);
- 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', () => {
,
);
- 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', () => {
,
);
- 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', () => {
,
);
- 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();
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,
diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
index 519c2d3f3a850..bcb74b6ea07f8 100644
--- a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
@@ -1148,14 +1148,11 @@ describe('ReactIncrementalErrorHandling', () => {
,
);
- 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();
expect(() => {
expect(Scheduler).toFlushAndThrow('Oops!');
- }).toErrorDev(
- [
- 'Warning: The 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 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',
+ ]);
});
});
diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js
index a88cd8e3a89fd..08c569c23950f 100644
--- a/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js
@@ -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();
addComment('Update');
diff --git a/packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js b/packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js
index 03c5ad4eec660..34d854f78cdd6 100644
--- a/packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js
@@ -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')]);
diff --git a/packages/react/src/__tests__/ReactStrictMode-test.js b/packages/react/src/__tests__/ReactStrictMode-test.js
index 15b2ce719c767..3acdab4ac3b52 100644
--- a/packages/react/src/__tests__/ReactStrictMode-test.js
+++ b/packages/react/src/__tests__/ReactStrictMode-test.js
@@ -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 **)',