@samitouri / QOS-React-2 / commits / 940f48b999

Avoid passing custom stacks to console.error (#18685)

* Detect double stacks in the new format in tests * Remove unnecessary uses of getStackByFiberInDevAndProd These all execute in the right execution context already. * Set the debug fiber around the cases that don't have an execution context * Remove stack detection in our console log overrides We never pass custom stacks as part of the args anymore. * Bonus: Don't append getStackAddendum to invariants We print component stacks for every error anyway so this is just duplicate information.

Sebastian Markbåge committed Apr 21, 2020 at 09:22 UTC 940f48b999a3131e77b2545bd7ae252ef27ae6d1
20 files changed +325 -404
packages/react-dom/src/__tests__/ReactComponent-test.js
+18 -62
@@ -15,15 +15,6 @@ let ReactDOMServer;
15 let ReactTestUtils;
16
17 describe('ReactComponent', () => {
18 - function normalizeCodeLocInfo(str) {
19 - return (
20 - str &&
21 - str.replace(/\n +(?:at|in) ([\S]+)[^\n]*/g, function(m, name) {
22 - return '\n in ' + name + ' (at **)';
23 - })
24 - );
25 - }
26 -
18 beforeEach(() => {
19 React = require('react');
20 ReactDOM = require('react-dom');
@@ -470,20 +461,11 @@ describe('ReactComponent', () => {
461 };
462 const element = <div>{[children]}</div>;
463 const container = document.createElement('div');
473 - let ex;
474 - try {
464 + expect(() => {
465 ReactDOM.render(element, container);
476 - } catch (e) {
477 - ex = e;
478 - }
479 - expect(ex).toBeDefined();
480 - expect(normalizeCodeLocInfo(ex.message)).toBe(
481 - 'Objects are not valid as a React child (found: object with keys {x, y, z}).' +
482 - (__DEV__
483 - ? ' If you meant to render a collection of children, use ' +
484 - 'an array instead.' +
485 - '\n in div (at **)'
486 - : ''),
466 + }).toThrowError(
467 + 'Objects are not valid as a React child (found: object with keys {x, y, z}). ' +
468 + 'If you meant to render a collection of children, use an array instead.',
469 );
470 });
471
@@ -499,21 +481,12 @@ describe('ReactComponent', () => {
481 }
482 }
483 const container = document.createElement('div');
502 - let ex;
503 - try {
484 + expect(() => {
485 ReactDOM.render(<Foo />, container);
505 - } catch (e) {
506 - ex = e;
507 - }
508 - expect(ex).toBeDefined();
509 - expect(normalizeCodeLocInfo(ex.message)).toBe(
486 + }).toThrowError(
487 'Objects are not valid as a React child (found: object with keys {a, b, c}).' +
511 - (__DEV__
512 - ? ' If you meant to render a collection of children, use ' +
513 - 'an array instead.\n' +
514 - ' in div (at **)\n' +
515 - ' in Foo (at **)'
516 - : ''),
488 + ' If you meant to render a collection of children, use an array ' +
489 + 'instead.',
490 );
491 });
492
@@ -524,20 +497,12 @@ describe('ReactComponent', () => {
497 z: <span />,
498 };
499 const element = <div>{[children]}</div>;
527 - let ex;
528 - try {
500 + expect(() => {
501 ReactDOMServer.renderToString(element);
530 - } catch (e) {
531 - ex = e;
532 - }
533 - expect(ex).toBeDefined();
534 - expect(normalizeCodeLocInfo(ex.message)).toBe(
535 - 'Objects are not valid as a React child (found: object with keys {x, y, z}).' +
536 - (__DEV__
537 - ? ' If you meant to render a collection of children, use ' +
538 - 'an array instead.' +
539 - '\n in div (at **)'
540 - : ''),
502 + }).toThrowError(
503 + 'Objects are not valid as a React child (found: object with keys {x, y, z}). ' +
504 + 'If you meant to render a collection of children, use ' +
505 + 'an array instead.',
506 );
507 });
508
@@ -553,21 +518,12 @@ describe('ReactComponent', () => {
518 }
519 }
520 const container = document.createElement('div');
556 - let ex;
557 - try {
521 + expect(() => {
522 ReactDOMServer.renderToString(<Foo />, container);
559 - } catch (e) {
560 - ex = e;
561 - }
562 - expect(ex).toBeDefined();
563 - expect(normalizeCodeLocInfo(ex.message)).toBe(
564 - 'Objects are not valid as a React child (found: object with keys {a, b, c}).' +
565 - (__DEV__
566 - ? ' If you meant to render a collection of children, use ' +
567 - 'an array instead.\n' +
568 - ' in div (at **)\n' +
569 - ' in Foo (at **)'
570 - : ''),
523 + }).toThrowError(
524 + 'Objects are not valid as a React child (found: object with keys {a, b, c}). ' +
525 + 'If you meant to render a collection of children, use ' +
526 + 'an array instead.',
527 );
528 });
529
packages/react-dom/src/__tests__/ReactDOMComponent-test.js
+12 -47
@@ -16,15 +16,6 @@ describe('ReactDOMComponent', () => {
16 let ReactDOMServer;
17 const ReactFeatureFlags = require('shared/ReactFeatureFlags');
18
19 - function normalizeCodeLocInfo(str) {
20 - return (
21 - str &&
22 - str.replace(/\n +(?:at|in) ([\S]+)[^\n]*/g, function(m, name) {
23 - return '\n in ' + name + ' (at **)';
24 - })
25 - );
26 - }
27 -
19 beforeEach(() => {
20 jest.resetModules();
21 React = require('react');
@@ -1320,36 +1311,24 @@ describe('ReactDOMComponent', () => {
1311
1312 it('should throw on children for void elements', () => {
1313 const container = document.createElement('div');
1323 - let caughtErr;
1324 - try {
1314 + expect(() => {
1315 ReactDOM.render(<input>children</input>, container);
1326 - } catch (err) {
1327 - caughtErr = err;
1328 - }
1329 - expect(caughtErr).not.toBe(undefined);
1330 - expect(normalizeCodeLocInfo(caughtErr.message)).toContain(
1316 + }).toThrowError(
1317 'input is a void element tag and must neither have `children` nor ' +
1332 - 'use `dangerouslySetInnerHTML`.' +
1333 - (__DEV__ ? '\n in input (at **)' : ''),
1318 + 'use `dangerouslySetInnerHTML`.',
1319 );
1320 });
1321
1322 it('should throw on dangerouslySetInnerHTML for void elements', () => {
1323 const container = document.createElement('div');
1339 - let caughtErr;
1340 - try {
1324 + expect(() => {
1325 ReactDOM.render(
1326 <input dangerouslySetInnerHTML={{__html: 'content'}} />,
1327 container,
1328 );
1345 - } catch (err) {
1346 - caughtErr = err;
1347 - }
1348 - expect(caughtErr).not.toBe(undefined);
1349 - expect(normalizeCodeLocInfo(caughtErr.message)).toContain(
1329 + }).toThrowError(
1330 'input is a void element tag and must neither have `children` nor ' +
1351 - 'use `dangerouslySetInnerHTML`.' +
1352 - (__DEV__ ? '\n in input (at **)' : ''),
1331 + 'use `dangerouslySetInnerHTML`.',
1332 );
1333 });
1334
@@ -1461,18 +1440,11 @@ describe('ReactDOMComponent', () => {
1440 }
1441
1442 const container = document.createElement('div');
1464 - let caughtErr;
1465 - try {
1443 + expect(() => {
1444 ReactDOM.render(<X />, container);
1467 - } catch (err) {
1468 - caughtErr = err;
1469 - }
1470 -
1471 - expect(caughtErr).not.toBe(undefined);
1472 - expect(normalizeCodeLocInfo(caughtErr.message)).toContain(
1445 + }).toThrowError(
1446 'input is a void element tag and must neither have `children` ' +
1474 - 'nor use `dangerouslySetInnerHTML`.' +
1475 - (__DEV__ ? '\n in input (at **)' + '\n in X (at **)' : ''),
1447 + 'nor use `dangerouslySetInnerHTML`.',
1448 );
1449 });
1450
@@ -1627,19 +1599,12 @@ describe('ReactDOMComponent', () => {
1599 }
1600 }
1601
1630 - let caughtErr;
1631 - try {
1602 + expect(() => {
1603 ReactDOM.render(<Animal />, container);
1633 - } catch (err) {
1634 - caughtErr = err;
1635 - }
1636 -
1637 - expect(caughtErr).not.toBe(undefined);
1638 - expect(normalizeCodeLocInfo(caughtErr.message)).toContain(
1604 + }).toThrowError(
1605 'The `style` prop expects a mapping from style properties to values, ' +
1606 "not a string. For example, style={{marginRight: spacing + 'em'}} " +
1641 - 'when using JSX.' +
1642 - (__DEV__ ? '\n in div (at **)' + '\n in Animal (at **)' : ''),
1607 + 'when using JSX.',
1608 );
1609 });
1610
packages/react-dom/src/__tests__/ReactServerRendering-test.js
+3 -18
@@ -17,15 +17,6 @@ let ReactCurrentDispatcher;
17 const enableSuspenseServerRenderer = require('shared/ReactFeatureFlags')
18 .enableSuspenseServerRenderer;
19
20 -function normalizeCodeLocInfo(str) {
21 - return (
22 - str &&
23 - str.replace(/\n +(?:at|in) ([\S]+)[^\n]*/g, function(m, name) {
24 - return '\n in ' + name + ' (at **)';
25 - })
26 - );
27 -}
28 -
20 describe('ReactDOMServer', () => {
21 beforeEach(() => {
22 jest.resetModules();
@@ -172,17 +163,11 @@ describe('ReactDOMServer', () => {
163 });
164
165 it('should throw prop mapping error for an <iframe /> with invalid props', () => {
175 - let caughtErr;
176 - try {
166 + expect(() => {
167 ReactDOMServer.renderToString(<iframe style="border:none;" />);
178 - } catch (err) {
179 - caughtErr = err;
180 - }
181 - expect(caughtErr).not.toBe(undefined);
182 - expect(normalizeCodeLocInfo(caughtErr.message)).toContain(
168 + }).toThrowError(
169 'The `style` prop expects a mapping from style properties to values, not ' +
184 - "a string. For example, style={{marginRight: spacing + 'em'}} when using JSX." +
185 - (__DEV__ ? '\n in iframe (at **)' : ''),
170 + "a string. For example, style={{marginRight: spacing + 'em'}} when using JSX.",
171 );
172 });
173
packages/react-dom/src/shared/assertValidProps.js
+2 -12
@@ -6,19 +6,11 @@
6 */
7
8 import invariant from 'shared/invariant';
9 -// TODO: We can remove this if we add invariantWithStack()
10 -// or add stack by default to invariants where possible.
11 -import ReactSharedInternals from 'shared/ReactSharedInternals';
9
10 import voidElementTags from './voidElementTags';
11
12 const HTML = '__html';
13
17 -let ReactDebugCurrentFrame = null;
18 -if (__DEV__) {
19 - ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
20 -}
21 -
14 function assertValidProps(tag: string, props: ?Object) {
15 if (!props) {
16 return;
@@ -28,9 +20,8 @@ function assertValidProps(tag: string, props: ?Object) {
20 invariant(
21 props.children == null && props.dangerouslySetInnerHTML == null,
22 '%s is a void element tag and must neither have `children` nor ' +
31 - 'use `dangerouslySetInnerHTML`.%s',
23 + 'use `dangerouslySetInnerHTML`.',
24 tag,
33 - __DEV__ ? ReactDebugCurrentFrame.getStackAddendum() : '',
25 );
26 }
27 if (props.dangerouslySetInnerHTML != null) {
@@ -64,8 +55,7 @@ function assertValidProps(tag: string, props: ?Object) {
55 props.style == null || typeof props.style === 'object',
56 'The `style` prop expects a mapping from style properties to values, ' +
57 "not a string. For example, style={{marginRight: spacing + 'em'}} when " +
67 - 'using JSX.%s',
68 - __DEV__ ? ReactDebugCurrentFrame.getStackAddendum() : '',
58 + 'using JSX.',
59 );
60 }
61
packages/react-dom/src/shared/sanitizeURL.js
+1 -8
@@ -8,14 +8,8 @@
8 */
9
10 import invariant from 'shared/invariant';
11 -import ReactSharedInternals from 'shared/ReactSharedInternals';
11 import {disableJavaScriptURLs} from 'shared/ReactFeatureFlags';
12
14 -let ReactDebugCurrentFrame = ((null: any): {getStackAddendum(): string, ...});
15 -if (__DEV__) {
16 - ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
17 -}
18 -
13 // A javascript: URL can contain leading C0 control or \u0020 SPACE,
14 // and any newline or tab are filtered out as if they're not part of the URL.
15 // https://url.spec.whatwg.org/#url-parsing
@@ -34,8 +28,7 @@ function sanitizeURL(url: string) {
28 if (disableJavaScriptURLs) {
29 invariant(
30 !isJavaScriptProtocol.test(url),
37 - 'React has blocked a javascript: URL as a security precaution.%s',
38 - __DEV__ ? ReactDebugCurrentFrame.getStackAddendum() : '',
31 + 'React has blocked a javascript: URL as a security precaution.',
32 );
33 } else if (__DEV__) {
34 if (!didWarn && isJavaScriptProtocol.test(url)) {
packages/react-reconciler/src/ReactChildFiber.new.js
+5 -14
@@ -44,7 +44,6 @@ import {
44 createFiberFromPortal,
45 } from './ReactFiber.new';
46 import {emptyRefsObject} from './ReactFiberClassComponent.new';
47 -import {getStackByFiberInDevAndProd} from './ReactFiberComponentStack';
47 import {getCurrentFiberStackInDev} from './ReactCurrentFiber';
48 import {isCompatibleFamilyForHotReloading} from './ReactFiberHotReloading.new';
49 import {StrictMode} from './ReactTypeOfMode';
@@ -136,10 +135,9 @@ function coerceRef(
135 'will be removed in a future major release. We recommend using ' +
136 'useRef() or createRef() instead. ' +
137 'Learn more about using refs safely here: ' +
139 - 'https://fb.me/react-strict-mode-string-ref%s',
138 + 'https://fb.me/react-strict-mode-string-ref',
139 componentName,
140 mixedRef,
142 - getStackByFiberInDevAndProd(returnFiber),
141 );
142 } else {
143 console.error(
@@ -147,9 +145,8 @@ function coerceRef(
145 'String refs are a source of potential bugs and should be avoided. ' +
146 'We recommend using useRef() or createRef() instead. ' +
147 'Learn more about using refs safely here: ' +
150 - 'https://fb.me/react-strict-mode-string-ref%s',
148 + 'https://fb.me/react-strict-mode-string-ref',
149 mixedRef,
152 - getStackByFiberInDevAndProd(returnFiber),
150 );
151 }
152 didWarnAboutStringRefs[componentName] = true;
@@ -223,20 +220,14 @@ function coerceRef(
220
221 function throwOnInvalidObjectType(returnFiber: Fiber, newChild: Object) {
222 if (returnFiber.type !== 'textarea') {
226 - let addendum = '';
227 - if (__DEV__) {
228 - addendum =
229 - ' If you meant to render a collection of children, use an array ' +
230 - 'instead.' +
231 - getCurrentFiberStackInDev();
232 - }
223 invariant(
224 false,
235 - 'Objects are not valid as a React child (found: %s).%s',
225 + 'Objects are not valid as a React child (found: %s). ' +
226 + 'If you meant to render a collection of children, use an array ' +
227 + 'instead.',
228 Object.prototype.toString.call(newChild) === '[object Object]'
229 ? 'object with keys {' + Object.keys(newChild).join(', ') + '}'
230 : newChild,
239 - addendum,
231 );
232 }
233 }
packages/react-reconciler/src/ReactChildFiber.old.js
+4 -14
@@ -44,7 +44,6 @@ import {
44 createFiberFromPortal,
45 } from './ReactFiber.old';
46 import {emptyRefsObject} from './ReactFiberClassComponent.old';
47 -import {getStackByFiberInDevAndProd} from './ReactFiberComponentStack';
47 import {getCurrentFiberStackInDev} from './ReactCurrentFiber';
48 import {isCompatibleFamilyForHotReloading} from './ReactFiberHotReloading.old';
49 import {StrictMode} from './ReactTypeOfMode';
@@ -136,10 +135,9 @@ function coerceRef(
135 'will be removed in a future major release. We recommend using ' +
136 'useRef() or createRef() instead. ' +
137 'Learn more about using refs safely here: ' +
139 - 'https://fb.me/react-strict-mode-string-ref%s',
138 + 'https://fb.me/react-strict-mode-string-ref',
139 componentName,
140 mixedRef,
142 - getStackByFiberInDevAndProd(returnFiber),
141 );
142 } else {
143 console.error(
@@ -147,9 +145,8 @@ function coerceRef(
145 'String refs are a source of potential bugs and should be avoided. ' +
146 'We recommend using useRef() or createRef() instead. ' +
147 'Learn more about using refs safely here: ' +
150 - 'https://fb.me/react-strict-mode-string-ref%s',
148 + 'https://fb.me/react-strict-mode-string-ref',
149 mixedRef,
152 - getStackByFiberInDevAndProd(returnFiber),
150 );
151 }
152 didWarnAboutStringRefs[componentName] = true;
@@ -223,20 +220,13 @@ function coerceRef(
220
221 function throwOnInvalidObjectType(returnFiber: Fiber, newChild: Object) {
222 if (returnFiber.type !== 'textarea') {
226 - let addendum = '';
227 - if (__DEV__) {
228 - addendum =
229 - ' If you meant to render a collection of children, use an array ' +
230 - 'instead.' +
231 - getCurrentFiberStackInDev();
232 - }
223 invariant(
224 false,
235 - 'Objects are not valid as a React child (found: %s).%s',
225 + 'Objects are not valid as a React child (found: %s). ' +
226 + 'If you meant to render a collection of children, use an array instead.',
227 Object.prototype.toString.call(newChild) === '[object Object]'
228 ? 'object with keys {' + Object.keys(newChild).join(', ') + '}'
229 : newChild,
239 - addendum,
230 );
231 }
232 }
packages/react-reconciler/src/ReactFiberCommitWork.new.js
+2 -5
@@ -73,7 +73,6 @@ import getComponentName from 'shared/getComponentName';
73 import invariant from 'shared/invariant';
74
75 import {onCommitUnmount} from './ReactFiberDevToolsHook.new';
76 -import {getStackByFiberInDevAndProd} from './ReactFiberComponentStack';
76 import {resolveDefaultProps} from './ReactFiberLazyComponent.new';
77 import {
78 getCommitTime,
@@ -368,9 +367,8 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
367 }
368 console.error(
369 'An effect function must not return anything besides a function, ' +
371 - 'which is used for clean-up.%s%s',
370 + 'which is used for clean-up.%s',
371 addendum,
373 - getStackByFiberInDevAndProd(finishedWork),
372 );
373 }
374 }
@@ -890,9 +888,8 @@ function commitAttachRef(finishedWork: Fiber) {
888 if (!ref.hasOwnProperty('current')) {
889 console.error(
890 'Unexpected ref object provided for %s. ' +
893 - 'Use either a ref-setter function or React.createRef().%s',
891 + 'Use either a ref-setter function or React.createRef().',
892 getComponentName(finishedWork.type),
895 - getStackByFiberInDevAndProd(finishedWork),
893 );
894 }
895 }
packages/react-reconciler/src/ReactFiberCommitWork.old.js
+2 -5
@@ -73,7 +73,6 @@ import getComponentName from 'shared/getComponentName';
73 import invariant from 'shared/invariant';
74
75 import {onCommitUnmount} from './ReactFiberDevToolsHook.old';
76 -import {getStackByFiberInDevAndProd} from './ReactFiberComponentStack';
76 import {resolveDefaultProps} from './ReactFiberLazyComponent.old';
77 import {
78 getCommitTime,
@@ -368,9 +367,8 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
367 }
368 console.error(
369 'An effect function must not return anything besides a function, ' +
371 - 'which is used for clean-up.%s%s',
370 + 'which is used for clean-up.%s',
371 addendum,
373 - getStackByFiberInDevAndProd(finishedWork),
372 );
373 }
374 }
@@ -890,9 +888,8 @@ function commitAttachRef(finishedWork: Fiber) {
888 if (!ref.hasOwnProperty('current')) {
889 console.error(
890 'Unexpected ref object provided for %s. ' +
893 - 'Use either a ref-setter function or React.createRef().%s',
891 + 'Use either a ref-setter function or React.createRef().',
892 getComponentName(finishedWork.type),
895 - getStackByFiberInDevAndProd(finishedWork),
893 );
894 }
895 }
packages/react-reconciler/src/ReactFiberReconciler.new.js
+37 -25
@@ -66,10 +66,11 @@ import {
66 act,
67 } from './ReactFiberWorkLoop.new';
68 import {createUpdate, enqueueUpdate} from './ReactUpdateQueue.new';
69 -import {getStackByFiberInDevAndProd} from './ReactFiberComponentStack';
69 import {
70 isRendering as ReactCurrentFiberIsRendering,
71 current as ReactCurrentFiberCurrent,
72 + resetCurrentFiber as resetCurrentDebugFiberInDEV,
73 + setCurrentFiber as setCurrentDebugFiberInDEV,
74 } from './ReactCurrentFiber';
75 import {StrictMode} from './ReactTypeOfMode';
76 import {
@@ -176,30 +177,41 @@ function findHostInstanceWithWarning(
177 const componentName = getComponentName(fiber.type) || 'Component';
178 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
179 didWarnAboutFindNodeInStrictMode[componentName] = true;
179 - if (fiber.mode & StrictMode) {
180 - console.error(
181 - '%s is deprecated in StrictMode. ' +
182 - '%s was passed an instance of %s which is inside StrictMode. ' +
183 - 'Instead, add a ref directly to the element you want to reference. ' +
184 - 'Learn more about using refs safely here: ' +
185 - 'https://fb.me/react-strict-mode-find-node%s',
186 - methodName,
187 - methodName,
188 - componentName,
189 - getStackByFiberInDevAndProd(hostFiber),
190 - );
191 - } else {
192 - console.error(
193 - '%s is deprecated in StrictMode. ' +
194 - '%s was passed an instance of %s which renders StrictMode children. ' +
195 - 'Instead, add a ref directly to the element you want to reference. ' +
196 - 'Learn more about using refs safely here: ' +
197 - 'https://fb.me/react-strict-mode-find-node%s',
198 - methodName,
199 - methodName,
200 - componentName,
201 - getStackByFiberInDevAndProd(hostFiber),
202 - );
180 +
181 + const previousFiber = ReactCurrentFiberCurrent;
182 + try {
183 + setCurrentDebugFiberInDEV(hostFiber);
184 + if (fiber.mode & StrictMode) {
185 + console.error(
186 + '%s is deprecated in StrictMode. ' +
187 + '%s was passed an instance of %s which is inside StrictMode. ' +
188 + 'Instead, add a ref directly to the element you want to reference. ' +
189 + 'Learn more about using refs safely here: ' +
190 + 'https://fb.me/react-strict-mode-find-node',
191 + methodName,
192 + methodName,
193 + componentName,
194 + );
195 + } else {
196 + console.error(
197 + '%s is deprecated in StrictMode. ' +
198 + '%s was passed an instance of %s which renders StrictMode children. ' +
199 + 'Instead, add a ref directly to the element you want to reference. ' +
200 + 'Learn more about using refs safely here: ' +
201 + 'https://fb.me/react-strict-mode-find-node',
202 + methodName,
203 + methodName,
204 + componentName,
205 + );
206 + }
207 + } finally {
208 + // Ideally this should reset to previous but this shouldn't be called in
209 + // render and there's another warning for that anyway.
210 + if (previousFiber) {
211 + setCurrentDebugFiberInDEV(previousFiber);
212 + } else {
213 + resetCurrentDebugFiberInDEV();
214 + }
215 }
216 }
217 }
packages/react-reconciler/src/ReactFiberReconciler.old.js
+37 -25
@@ -66,10 +66,11 @@ import {
66 act,
67 } from './ReactFiberWorkLoop.old';
68 import {createUpdate, enqueueUpdate} from './ReactUpdateQueue.old';
69 -import {getStackByFiberInDevAndProd} from './ReactFiberComponentStack';
69 import {
70 isRendering as ReactCurrentFiberIsRendering,
71 current as ReactCurrentFiberCurrent,
72 + resetCurrentFiber as resetCurrentDebugFiberInDEV,
73 + setCurrentFiber as setCurrentDebugFiberInDEV,
74 } from './ReactCurrentFiber';
75 import {StrictMode} from './ReactTypeOfMode';
76 import {
@@ -176,30 +177,41 @@ function findHostInstanceWithWarning(
177 const componentName = getComponentName(fiber.type) || 'Component';
178 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
179 didWarnAboutFindNodeInStrictMode[componentName] = true;
179 - if (fiber.mode & StrictMode) {
180 - console.error(
181 - '%s is deprecated in StrictMode. ' +
182 - '%s was passed an instance of %s which is inside StrictMode. ' +
183 - 'Instead, add a ref directly to the element you want to reference. ' +
184 - 'Learn more about using refs safely here: ' +
185 - 'https://fb.me/react-strict-mode-find-node%s',
186 - methodName,
187 - methodName,
188 - componentName,
189 - getStackByFiberInDevAndProd(hostFiber),
190 - );
191 - } else {
192 - console.error(
193 - '%s is deprecated in StrictMode. ' +
194 - '%s was passed an instance of %s which renders StrictMode children. ' +
195 - 'Instead, add a ref directly to the element you want to reference. ' +
196 - 'Learn more about using refs safely here: ' +
197 - 'https://fb.me/react-strict-mode-find-node%s',
198 - methodName,
199 - methodName,
200 - componentName,
201 - getStackByFiberInDevAndProd(hostFiber),
202 - );
180 +
181 + const previousFiber = ReactCurrentFiberCurrent;
182 + try {
183 + setCurrentDebugFiberInDEV(hostFiber);
184 + if (fiber.mode & StrictMode) {
185 + console.error(
186 + '%s is deprecated in StrictMode. ' +
187 + '%s was passed an instance of %s which is inside StrictMode. ' +
188 + 'Instead, add a ref directly to the element you want to reference. ' +
189 + 'Learn more about using refs safely here: ' +
190 + 'https://fb.me/react-strict-mode-find-node',
191 + methodName,
192 + methodName,
193 + componentName,
194 + );
195 + } else {
196 + console.error(
197 + '%s is deprecated in StrictMode. ' +
198 + '%s was passed an instance of %s which renders StrictMode children. ' +
199 + 'Instead, add a ref directly to the element you want to reference. ' +
200 + 'Learn more about using refs safely here: ' +
201 + 'https://fb.me/react-strict-mode-find-node',
202 + methodName,
203 + methodName,
204 + componentName,
205 + );
206 + }
207 + } finally {
208 + // Ideally this should reset to previous but this shouldn't be called in
209 + // render and there's another warning for that anyway.
210 + if (previousFiber) {
211 + setCurrentDebugFiberInDEV(previousFiber);
212 + } else {
213 + resetCurrentDebugFiberInDEV();
214 + }
215 }
216 }
217 }
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+70 -47
@@ -180,9 +180,9 @@ import {
180 // DEV stuff
181 import getComponentName from 'shared/getComponentName';
182 import ReactStrictModeWarnings from './ReactStrictModeWarnings.new';
183 -import {getStackByFiberInDevAndProd} from './ReactFiberComponentStack';
183 import {
184 isRendering as ReactCurrentDebugFiberIsRenderingInDEV,
185 + current as ReactCurrentFiberCurrent,
186 resetCurrentFiber as resetCurrentDebugFiberInDEV,
187 setCurrentFiber as setCurrentDebugFiberInDEV,
188 } from './ReactCurrentFiber';
@@ -2927,15 +2927,24 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
2927 // 1. Updating an ancestor that a component had registered itself with on mount.
2928 // 2. Resetting state when a component is hidden after going offscreen.
2929 } else {
2930 - console.error(
2931 - "Can't perform a React state update on an unmounted component. This " +
2932 - 'is a no-op, but it indicates a memory leak in your application. To ' +
2933 - 'fix, cancel all subscriptions and asynchronous tasks in %s.%s',
2934 - tag === ClassComponent
2935 - ? 'the componentWillUnmount method'
2936 - : 'a useEffect cleanup function',
2937 - getStackByFiberInDevAndProd(fiber),
2938 - );
2930 + const previousFiber = ReactCurrentFiberCurrent;
2931 + try {
2932 + setCurrentDebugFiberInDEV(fiber);
2933 + console.error(
2934 + "Can't perform a React state update on an unmounted component. This " +
2935 + 'is a no-op, but it indicates a memory leak in your application. To ' +
2936 + 'fix, cancel all subscriptions and asynchronous tasks in %s.',
2937 + tag === ClassComponent
2938 + ? 'the componentWillUnmount method'
2939 + : 'a useEffect cleanup function',
2940 + );
2941 + } finally {
2942 + if (previousFiber) {
2943 + setCurrentDebugFiberInDEV(fiber);
2944 + } else {
2945 + resetCurrentDebugFiberInDEV();
2946 + }
2947 + }
2948 }
2949 }
2950 }
@@ -3072,25 +3081,33 @@ export function warnIfNotScopedWithMatchingAct(fiber: Fiber): void {
3081 IsSomeRendererActing.current === true &&
3082 IsThisRendererActing.current !== true
3083 ) {
3075 - console.error(
3076 - "It looks like you're using the wrong act() around your test interactions.\n" +
3077 - 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' +
3078 - '// for react-dom:\n' +
3079 - // Break up imports to avoid accidentally parsing them as dependencies.
3080 - 'import {act} fr' +
3081 - "om 'react-dom/test-utils';\n" +
3082 - '// ...\n' +
3083 - 'act(() => ...);\n\n' +
3084 - '// for react-test-renderer:\n' +
3085 - // Break up imports to avoid accidentally parsing them as dependencies.
3086 - 'import TestRenderer fr' +
3087 - "om react-test-renderer';\n" +
3088 - 'const {act} = TestRenderer;\n' +
3089 - '// ...\n' +
3090 - 'act(() => ...);' +
3091 - '%s',
3092 - getStackByFiberInDevAndProd(fiber),
3093 - );
3084 + const previousFiber = ReactCurrentFiberCurrent;
3085 + try {
3086 + setCurrentDebugFiberInDEV(fiber);
3087 + console.error(
3088 + "It looks like you're using the wrong act() around your test interactions.\n" +
3089 + 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' +
3090 + '// for react-dom:\n' +
3091 + // Break up imports to avoid accidentally parsing them as dependencies.
3092 + 'import {act} fr' +
3093 + "om 'react-dom/test-utils';\n" +
3094 + '// ...\n' +
3095 + 'act(() => ...);\n\n' +
3096 + '// for react-test-renderer:\n' +
3097 + // Break up imports to avoid accidentally parsing them as dependencies.
3098 + 'import TestRenderer fr' +
3099 + "om react-test-renderer';\n" +
3100 + 'const {act} = TestRenderer;\n' +
3101 + '// ...\n' +
3102 + 'act(() => ...);',
3103 + );
3104 + } finally {
3105 + if (previousFiber) {
3106 + setCurrentDebugFiberInDEV(fiber);
3107 + } else {
3108 + resetCurrentDebugFiberInDEV();
3109 + }
3110 + }
3111 }
3112 }
3113 }
@@ -3113,10 +3130,8 @@ export function warnIfNotCurrentlyActingEffectsInDEV(fiber: Fiber): void {
3130 '/* assert on the output */\n\n' +
3131 "This ensures that you're testing the behavior the user would see " +
3132 'in the browser.' +
3116 - ' Learn more at https://fb.me/react-wrap-tests-with-act' +
3117 - '%s',
3133 + ' Learn more at https://fb.me/react-wrap-tests-with-act',
3134 getComponentName(fiber.type),
3119 - getStackByFiberInDevAndProd(fiber),
3135 );
3136 }
3137 }
@@ -3130,21 +3145,29 @@ function warnIfNotCurrentlyActingUpdatesInDEV(fiber: Fiber): void {
3145 IsSomeRendererActing.current === false &&
3146 IsThisRendererActing.current === false
3147 ) {
3133 - console.error(
3134 - 'An update to %s inside a test was not wrapped in act(...).\n\n' +
3135 - 'When testing, code that causes React state updates should be ' +
3136 - 'wrapped into act(...):\n\n' +
3137 - 'act(() => {\n' +
3138 - ' /* fire events that update state */\n' +
3139 - '});\n' +
3140 - '/* assert on the output */\n\n' +
3141 - "This ensures that you're testing the behavior the user would see " +
3142 - 'in the browser.' +
3143 - ' Learn more at https://fb.me/react-wrap-tests-with-act' +
3144 - '%s',
3145 - getComponentName(fiber.type),
3146 - getStackByFiberInDevAndProd(fiber),
3147 - );
3148 + const previousFiber = ReactCurrentFiberCurrent;
3149 + try {
3150 + setCurrentDebugFiberInDEV(fiber);
3151 + console.error(
3152 + 'An update to %s inside a test was not wrapped in act(...).\n\n' +
3153 + 'When testing, code that causes React state updates should be ' +
3154 + 'wrapped into act(...):\n\n' +
3155 + 'act(() => {\n' +
3156 + ' /* fire events that update state */\n' +
3157 + '});\n' +
3158 + '/* assert on the output */\n\n' +
3159 + "This ensures that you're testing the behavior the user would see " +
3160 + 'in the browser.' +
3161 + ' Learn more at https://fb.me/react-wrap-tests-with-act',
3162 + getComponentName(fiber.type),
3163 + );
3164 + } finally {
3165 + if (previousFiber) {
3166 + setCurrentDebugFiberInDEV(fiber);
3167 + } else {
3168 + resetCurrentDebugFiberInDEV();
3169 + }
3170 + }
3171 }
3172 }
3173 }
packages/react-reconciler/src/ReactFiberWorkLoop.old.js
+70 -47
@@ -178,9 +178,9 @@ import {
178 // DEV stuff
179 import getComponentName from 'shared/getComponentName';
180 import ReactStrictModeWarnings from './ReactStrictModeWarnings.old';
181 -import {getStackByFiberInDevAndProd} from './ReactFiberComponentStack';
181 import {
182 isRendering as ReactCurrentDebugFiberIsRenderingInDEV,
183 + current as ReactCurrentFiberCurrent,
184 resetCurrentFiber as resetCurrentDebugFiberInDEV,
185 setCurrentFiber as setCurrentDebugFiberInDEV,
186 } from './ReactCurrentFiber';
@@ -2949,15 +2949,24 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
2949 // 1. Updating an ancestor that a component had registered itself with on mount.
2950 // 2. Resetting state when a component is hidden after going offscreen.
2951 } else {
2952 - console.error(
2953 - "Can't perform a React state update on an unmounted component. This " +
2954 - 'is a no-op, but it indicates a memory leak in your application. To ' +
2955 - 'fix, cancel all subscriptions and asynchronous tasks in %s.%s',
2956 - tag === ClassComponent
2957 - ? 'the componentWillUnmount method'
2958 - : 'a useEffect cleanup function',
2959 - getStackByFiberInDevAndProd(fiber),
2960 - );
2952 + const previousFiber = ReactCurrentFiberCurrent;
2953 + try {
2954 + setCurrentDebugFiberInDEV(fiber);
2955 + console.error(
2956 + "Can't perform a React state update on an unmounted component. This " +
2957 + 'is a no-op, but it indicates a memory leak in your application. To ' +
2958 + 'fix, cancel all subscriptions and asynchronous tasks in %s.',
2959 + tag === ClassComponent
2960 + ? 'the componentWillUnmount method'
2961 + : 'a useEffect cleanup function',
2962 + );
2963 + } finally {
2964 + if (previousFiber) {
2965 + setCurrentDebugFiberInDEV(fiber);
2966 + } else {
2967 + resetCurrentDebugFiberInDEV();
2968 + }
2969 + }
2970 }
2971 }
2972 }
@@ -3094,25 +3103,33 @@ export function warnIfNotScopedWithMatchingAct(fiber: Fiber): void {
3103 IsSomeRendererActing.current === true &&
3104 IsThisRendererActing.current !== true
3105 ) {
3097 - console.error(
3098 - "It looks like you're using the wrong act() around your test interactions.\n" +
3099 - 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' +
3100 - '// for react-dom:\n' +
3101 - // Break up imports to avoid accidentally parsing them as dependencies.
3102 - 'import {act} fr' +
3103 - "om 'react-dom/test-utils';\n" +
3104 - '// ...\n' +
3105 - 'act(() => ...);\n\n' +
3106 - '// for react-test-renderer:\n' +
3107 - // Break up imports to avoid accidentally parsing them as dependencies.
3108 - 'import TestRenderer fr' +
3109 - "om react-test-renderer';\n" +
3110 - 'const {act} = TestRenderer;\n' +
3111 - '// ...\n' +
3112 - 'act(() => ...);' +
3113 - '%s',
3114 - getStackByFiberInDevAndProd(fiber),
3115 - );
3106 + const previousFiber = ReactCurrentFiberCurrent;
3107 + try {
3108 + setCurrentDebugFiberInDEV(fiber);
3109 + console.error(
3110 + "It looks like you're using the wrong act() around your test interactions.\n" +
3111 + 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' +
3112 + '// for react-dom:\n' +
3113 + // Break up imports to avoid accidentally parsing them as dependencies.
3114 + 'import {act} fr' +
3115 + "om 'react-dom/test-utils';\n" +
3116 + '// ...\n' +
3117 + 'act(() => ...);\n\n' +
3118 + '// for react-test-renderer:\n' +
3119 + // Break up imports to avoid accidentally parsing them as dependencies.
3120 + 'import TestRenderer fr' +
3121 + "om react-test-renderer';\n" +
3122 + 'const {act} = TestRenderer;\n' +
3123 + '// ...\n' +
3124 + 'act(() => ...);',
3125 + );
3126 + } finally {
3127 + if (previousFiber) {
3128 + setCurrentDebugFiberInDEV(fiber);
3129 + } else {
3130 + resetCurrentDebugFiberInDEV();
3131 + }
3132 + }
3133 }
3134 }
3135 }
@@ -3135,10 +3152,8 @@ export function warnIfNotCurrentlyActingEffectsInDEV(fiber: Fiber): void {
3152 '/* assert on the output */\n\n' +
3153 "This ensures that you're testing the behavior the user would see " +
3154 'in the browser.' +
3138 - ' Learn more at https://fb.me/react-wrap-tests-with-act' +
3139 - '%s',
3155 + ' Learn more at https://fb.me/react-wrap-tests-with-act',
3156 getComponentName(fiber.type),
3141 - getStackByFiberInDevAndProd(fiber),
3157 );
3158 }
3159 }
@@ -3152,21 +3167,29 @@ function warnIfNotCurrentlyActingUpdatesInDEV(fiber: Fiber): void {
3167 IsSomeRendererActing.current === false &&
3168 IsThisRendererActing.current === false
3169 ) {
3155 - console.error(
3156 - 'An update to %s inside a test was not wrapped in act(...).\n\n' +
3157 - 'When testing, code that causes React state updates should be ' +
3158 - 'wrapped into act(...):\n\n' +
3159 - 'act(() => {\n' +
3160 - ' /* fire events that update state */\n' +
3161 - '});\n' +
3162 - '/* assert on the output */\n\n' +
3163 - "This ensures that you're testing the behavior the user would see " +
3164 - 'in the browser.' +
3165 - ' Learn more at https://fb.me/react-wrap-tests-with-act' +
3166 - '%s',
3167 - getComponentName(fiber.type),
3168 - getStackByFiberInDevAndProd(fiber),
3169 - );
3170 + const previousFiber = ReactCurrentFiberCurrent;
3171 + try {
3172 + setCurrentDebugFiberInDEV(fiber);
3173 + console.error(
3174 + 'An update to %s inside a test was not wrapped in act(...).\n\n' +
3175 + 'When testing, code that causes React state updates should be ' +
3176 + 'wrapped into act(...):\n\n' +
3177 + 'act(() => {\n' +
3178 + ' /* fire events that update state */\n' +
3179 + '});\n' +
3180 + '/* assert on the output */\n\n' +
3181 + "This ensures that you're testing the behavior the user would see " +
3182 + 'in the browser.' +
3183 + ' Learn more at https://fb.me/react-wrap-tests-with-act',
3184 + getComponentName(fiber.type),
3185 + );
3186 + } finally {
3187 + if (previousFiber) {
3188 + setCurrentDebugFiberInDEV(fiber);
3189 + } else {
3190 + resetCurrentDebugFiberInDEV();
3191 + }
3192 + }
3193 }
3194 }
3195 }
packages/react-reconciler/src/ReactStrictModeWarnings.new.js
+18 -14
@@ -9,8 +9,10 @@
9
10 import type {Fiber} from './ReactInternalTypes';
11
12 -import {getStackByFiberInDevAndProd} from './ReactFiberComponentStack';
13 -
12 +import {
13 + resetCurrentFiber as resetCurrentDebugFiberInDEV,
14 + setCurrentFiber as setCurrentDebugFiberInDEV,
15 +} from './ReactCurrentFiber';
16 import getComponentName from 'shared/getComponentName';
17 import {StrictMode} from './ReactTypeOfMode';
18
@@ -336,18 +338,20 @@ if (__DEV__) {
338 });
339
340 const sortedNames = setToSortedString(uniqueNames);
339 - const firstComponentStack = getStackByFiberInDevAndProd(firstFiber);
340 -
341 - console.error(
342 - 'Legacy context API has been detected within a strict-mode tree.' +
343 - '\n\nThe old API will be supported in all 16.x releases, but applications ' +
344 - 'using it should migrate to the new version.' +
345 - '\n\nPlease update the following components: %s' +
346 - '\n\nLearn more about this warning here: https://fb.me/react-legacy-context' +
347 - '%s',
348 - sortedNames,
349 - firstComponentStack,
350 - );
341 +
342 + try {
343 + setCurrentDebugFiberInDEV(firstFiber);
344 + console.error(
345 + 'Legacy context API has been detected within a strict-mode tree.' +
346 + '\n\nThe old API will be supported in all 16.x releases, but applications ' +
347 + 'using it should migrate to the new version.' +
348 + '\n\nPlease update the following components: %s' +
349 + '\n\nLearn more about this warning here: https://fb.me/react-legacy-context',
350 + sortedNames,
351 + );
352 + } finally {
353 + resetCurrentDebugFiberInDEV();
354 + }
355 },
356 );
357 };
packages/react-reconciler/src/ReactStrictModeWarnings.old.js
+18 -14
@@ -9,8 +9,10 @@
9
10 import type {Fiber} from './ReactInternalTypes';
11
12 -import {getStackByFiberInDevAndProd} from './ReactFiberComponentStack';
13 -
12 +import {
13 + resetCurrentFiber as resetCurrentDebugFiberInDEV,
14 + setCurrentFiber as setCurrentDebugFiberInDEV,
15 +} from './ReactCurrentFiber';
16 import getComponentName from 'shared/getComponentName';
17 import {StrictMode} from './ReactTypeOfMode';
18
@@ -336,18 +338,20 @@ if (__DEV__) {
338 });
339
340 const sortedNames = setToSortedString(uniqueNames);
339 - const firstComponentStack = getStackByFiberInDevAndProd(firstFiber);
340 -
341 - console.error(
342 - 'Legacy context API has been detected within a strict-mode tree.' +
343 - '\n\nThe old API will be supported in all 16.x releases, but applications ' +
344 - 'using it should migrate to the new version.' +
345 - '\n\nPlease update the following components: %s' +
346 - '\n\nLearn more about this warning here: https://fb.me/react-legacy-context' +
347 - '%s',
348 - sortedNames,
349 - firstComponentStack,
350 - );
341 +
342 + try {
343 + setCurrentDebugFiberInDEV(firstFiber);
344 + console.error(
345 + 'Legacy context API has been detected within a strict-mode tree.' +
346 + '\n\nThe old API will be supported in all 16.x releases, but applications ' +
347 + 'using it should migrate to the new version.' +
348 + '\n\nPlease update the following components: %s' +
349 + '\n\nLearn more about this warning here: https://fb.me/react-legacy-context',
350 + sortedNames,
351 + );
352 + } finally {
353 + resetCurrentDebugFiberInDEV();
354 + }
355 },
356 );
357 };
packages/react/src/ReactChildren.js
+3 -10
@@ -17,7 +17,6 @@ import {
17 } from 'shared/ReactSymbols';
18
19 import {isValidElement, cloneAndReplaceKey} from './ReactElement';
20 -import ReactDebugCurrentFrame from './ReactDebugCurrentFrame';
20
21 const SEPARATOR = '.';
22 const SUBSEPARATOR = ':';
@@ -190,21 +189,15 @@ function mapIntoArray(
189 );
190 }
191 } else if (type === 'object') {
193 - let addendum = '';
194 - if (__DEV__) {
195 - addendum =
196 - ' If you meant to render a collection of children, use an array ' +
197 - 'instead.' +
198 - ReactDebugCurrentFrame.getStackAddendum();
199 - }
192 const childrenString = '' + (children: any);
193 invariant(
194 false,
203 - 'Objects are not valid as a React child (found: %s).%s',
195 + 'Objects are not valid as a React child (found: %s). ' +
196 + 'If you meant to render a collection of children, use an array ' +
197 + 'instead.',
198 childrenString === '[object Object]'
199 ? 'object with keys {' + Object.keys((children: any)).join(', ') + '}'
200 : childrenString,
207 - addendum,
201 );
202 }
203 }
packages/shared/consoleWithStackDev.js
+5 -13
@@ -29,19 +29,11 @@ function printWarning(level, format, args) {
29 // When changing this logic, you might want to also
30 // update consoleWithStackDev.www.js as well.
31 if (__DEV__) {
32 - const hasExistingStack =
33 - args.length > 0 &&
34 - typeof args[args.length - 1] === 'string' &&
35 - args[args.length - 1].indexOf('\n in') === 0;
36 -
37 - if (!hasExistingStack) {
38 - const ReactDebugCurrentFrame =
39 - ReactSharedInternals.ReactDebugCurrentFrame;
40 - const stack = ReactDebugCurrentFrame.getStackAddendum();
41 - if (stack !== '') {
42 - format += '%s';
43 - args = args.concat([stack]);
44 - }
32 + const ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
33 + const stack = ReactDebugCurrentFrame.getStackAddendum();
34 + if (stack !== '') {
35 + format += '%s';
36 + args = args.concat([stack]);
37 }
38
39 const argsWithFormat = args.map(item => '' + item);
packages/shared/forks/consoleWithStackDev.www.js
+11 -18
@@ -22,24 +22,17 @@ export function error(format, ...args) {
22
23 function printWarning(level, format, args) {
24 if (__DEV__) {
25 - const hasExistingStack =
26 - args.length > 0 &&
27 - typeof args[args.length - 1] === 'string' &&
28 - args[args.length - 1].indexOf('\n in') === 0;
29 -
30 - if (!hasExistingStack) {
31 - const React = require('react');
32 - const ReactSharedInternals =
33 - React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
34 - // Defensive in case this is fired before React is initialized.
35 - if (ReactSharedInternals != null) {
36 - const ReactDebugCurrentFrame =
37 - ReactSharedInternals.ReactDebugCurrentFrame;
38 - const stack = ReactDebugCurrentFrame.getStackAddendum();
39 - if (stack !== '') {
40 - format += '%s';
41 - args.push(stack);
42 - }
25 + const React = require('react');
26 + const ReactSharedInternals =
27 + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
28 + // Defensive in case this is fired before React is initialized.
29 + if (ReactSharedInternals != null) {
30 + const ReactDebugCurrentFrame =
31 + ReactSharedInternals.ReactDebugCurrentFrame;
32 + const stack = ReactDebugCurrentFrame.getStackAddendum();
33 + if (stack !== '') {
34 + format += '%s';
35 + args.push(stack);
36 }
37 }
38 // TODO: don't ignore level and pass it down somewhere too.
scripts/error-codes/codes.json
+5 -5
@@ -30,7 +30,7 @@
30 "28": "Transaction.closeAll(): Cannot close transaction when none are open.",
31 "29": "accumulate(...): Accumulated items must be not be null or undefined.",
32 "30": "accumulateInto(...): Accumulated items must not be null or undefined.",
33 - "31": "Objects are not valid as a React child (found: %s).%s",
33 + "31": "Objects are not valid as a React child (found: %s). If you meant to render a collection of children, use an array instead.",
34 "32": "Unable to find element with ID %s.",
35 "33": "getNodeFromInstance: Invalid argument.",
36 "34": "React DOM tree root should always have a node reference.",
@@ -58,10 +58,10 @@
58 "56": "dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a worker thread. Make sure `window` and `document` are available globally before requiring React when unit testing or use ReactDOMServer.renderToString() for server rendering.",
59 "57": "dangerouslyReplaceNodeWithMarkup(...): Missing markup.",
60 "58": "dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the <html> node. This is because browser quirks make this unreliable and/or slow. If you want to render to the root you must use server rendering. See ReactDOMServer.renderToString().",
61 - "59": "%s is a void element tag and must not have `children` or use `props.dangerouslySetInnerHTML`.%s",
61 + "59": "%s is a void element tag and must not have `children` or use `props.dangerouslySetInnerHTML`.",
62 "60": "Can only set one of `children` or `props.dangerouslySetInnerHTML`.",
63 "61": "`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.",
64 - "62": "The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX.%s",
64 + "62": "The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX.",
65 "63": "Must be mounted to trap events",
66 "64": "trapBubbledEvent(...): Requires node to be rendered.",
67 "65": "Invalid tag: %s",
@@ -136,7 +136,7 @@
136 "134": "Touch data should have been recorded on start",
137 "135": "Cannot find single active touch",
138 "136": "Attempted to update component `%s` that has already been unmounted (or failed to mount).",
139 - "137": "%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.%s",
139 + "137": "%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.",
140 "138": "Touch object is missing identifier.",
141 "139": "ReactTestRenderer: .update() can't be called after unmount.",
142 "140": "Expected hook events to fire for the child before its parent includes it in onSetChildren().",
@@ -321,7 +321,7 @@
321 "320": "Expected ReactFiberErrorDialog.showErrorDialog to be a function.",
322 "321": "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.",
323 "322": "forwardRef requires a render function but was given %s.",
324 - "323": "React has blocked a javascript: URL as a security precaution.%s",
324 + "323": "React has blocked a javascript: URL as a security precaution.",
325 "324": "An event responder context was used outside of an event cycle. Use context.setTimeout() to use asynchronous responder context outside of event cycle .",
326 "325": "addRootEventTypes() found a duplicate root event type of \"%s\". This might be because the event type exists in the event responder \"rootEventTypes\" array or because of a previous addRootEventTypes() using this root event type.",
327 "326": "Expected a valid priority level",
scripts/jest/matchers/toWarnDev.js
+2 -1
@@ -65,7 +65,8 @@ const createMatcherFor = (consoleMethod, matcherName) =>
65 let caughtError;
66
67 const isLikelyAComponentStack = message =>
68 - typeof message === 'string' && message.includes('\n in ');
68 + typeof message === 'string' &&
69 + (message.includes('\n in ') || message.includes('\n at '));
70
71 const consoleSpy = (format, ...args) => {
72 // Ignore uncaught errors reported by jsdom