[tests] fix hidden use() warnings (#31984)
`spyOnDev` is such a footgun.
Ricky committed
Jan 6, 2025 at 14:12 UTC
83be48b9dee25737063ca64880f82ef9fea11737
1 file changed
+326
-107
packages/react-reconciler/src/__tests__/ReactUse-test.js
+326
-107
@@ -27,6 +27,7 @@ let waitForPaint;
27
let assertLog;
28
let waitForAll;
29
let waitForMicrotasks;
30
+let assertConsoleErrorDev;
31
32
describe('ReactUse', () => {
33
beforeEach(() => {
@@ -51,6 +52,7 @@ describe('ReactUse', () => {
52
waitForPaint = InternalTestUtils.waitForPaint;
53
waitFor = InternalTestUtils.waitFor;
54
waitForMicrotasks = InternalTestUtils.waitForMicrotasks;
55
+ assertConsoleErrorDev = InternalTestUtils.assertConsoleErrorDev;
56
57
pendingTextRequests = new Map();
58
});
@@ -246,16 +248,19 @@ describe('ReactUse', () => {
248
}
249
250
const root = ReactNoop.createRoot();
249
- await expect(async () => {
250
- await act(() => {
251
- startTransition(() => {
252
- root.render(<App />);
253
- });
251
+ await act(() => {
252
+ startTransition(() => {
253
+ root.render(<App />);
254
});
255
- }).toErrorDev([
255
+ });
256
+ assertConsoleErrorDev([
257
'A component was suspended by an uncached promise. Creating ' +
258
'promises inside a Client Component or hook is not yet ' +
258
- 'supported, except via a Suspense-compatible library or framework.',
259
+ 'supported, except via a Suspense-compatible library or framework.\n' +
260
+ (gate('enableOwnerStacks')
261
+ ? ''
262
+ : ' in Async (at **)\n' + ' in Suspense (at **)\n') +
263
+ ' in App (at **)',
264
]);
265
assertLog(['ABC']);
266
expect(root).toMatchRenderedOutput('ABC');
@@ -416,19 +421,30 @@ describe('ReactUse', () => {
421
}
422
423
const root = ReactNoop.createRoot();
419
- await expect(async () => {
420
- await act(() => {
421
- startTransition(() => {
422
- root.render(<App />);
423
- });
424
+ await act(() => {
425
+ startTransition(() => {
426
+ root.render(<App />);
427
});
425
- }).toErrorDev([
428
+ });
429
+ assertConsoleErrorDev([
430
'A component was suspended by an uncached promise. Creating ' +
431
'promises inside a Client Component or hook is not yet ' +
428
- 'supported, except via a Suspense-compatible library or framework.',
432
+ 'supported, except via a Suspense-compatible library or framework.\n' +
433
+ (gate('enableOwnerStacks')
434
+ ? ''
435
+ : ' in Async (at **)\n' +
436
+ ' in ErrorBoundary (at **)\n' +
437
+ ' in Suspense (at **)\n') +
438
+ ' in App (at **)',
439
'A component was suspended by an uncached promise. Creating ' +
440
'promises inside a Client Component or hook is not yet ' +
431
- 'supported, except via a Suspense-compatible library or framework.',
441
+ 'supported, except via a Suspense-compatible library or framework.\n' +
442
+ (gate('enableOwnerStacks')
443
+ ? ''
444
+ : ' in Async (at **)\n' +
445
+ ' in ErrorBoundary (at **)\n' +
446
+ ' in Suspense (at **)\n') +
447
+ ' in App (at **)',
448
]);
449
assertLog([
450
// First attempt. The uncached promise suspends.
@@ -560,6 +576,7 @@ describe('ReactUse', () => {
576
'allowed and can lead to unexpected behavior. To handle errors ' +
577
'triggered by `use`, wrap your component in a error boundary.',
578
);
579
+ console.error.mockRestore();
580
}
581
});
582
@@ -596,6 +613,13 @@ describe('ReactUse', () => {
613
resolveTextRequests('Async');
614
});
615
assertLog(['Async text requested [Async]', 'Async']);
616
+ assertConsoleErrorDev([
617
+ 'A component was suspended by an uncached promise. ' +
618
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
619
+ 'except via a Suspense-compatible library or framework.\n' +
620
+ ' in App (at **)\n' +
621
+ ' in Suspense (at **)',
622
+ ]);
623
expect(root).toMatchRenderedOutput('Async');
624
});
625
@@ -639,6 +663,13 @@ describe('ReactUse', () => {
663
});
664
// This time it finishes because it was during a retry.
665
assertLog(['Async text requested [Async]', 'Async']);
666
+ assertConsoleErrorDev([
667
+ 'A component was suspended by an uncached promise. ' +
668
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
669
+ 'except via a Suspense-compatible library or framework.\n' +
670
+ ' in App (at **)\n' +
671
+ ' in Suspense (at **)',
672
+ ]);
673
expect(root).toMatchRenderedOutput('Async');
674
});
675
@@ -886,6 +917,7 @@ describe('ReactUse', () => {
917
root.render(<ExcitingText text="Hello" />);
918
});
919
});
920
+
921
// Suspends while we wait for the async service to respond.
922
assertLog(['Compute uppercase: Hello', 'Async text requested [HELLO!]']);
923
expect(root).toMatchRenderedOutput(null);
@@ -894,6 +926,13 @@ describe('ReactUse', () => {
926
await act(() => {
927
resolveTextRequests('HELLO!');
928
});
929
+ assertConsoleErrorDev([
930
+ 'A component was suspended by an uncached promise. ' +
931
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
932
+ 'except via a Suspense-compatible library or framework.\n' +
933
+ ' in ExcitingText (at **)',
934
+ ]);
935
+
936
assertLog([
937
// We shouldn't run the uppercase computation again, because we can reuse
938
// the computation from the previous attempt.
@@ -931,6 +970,13 @@ describe('ReactUse', () => {
970
resolveTextRequests('apple');
971
});
972
assertLog(['Async text requested [apple]', 'apple carrot']);
973
+ assertConsoleErrorDev([
974
+ 'A component was suspended by an uncached promise. ' +
975
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
976
+ 'except via a Suspense-compatible library or framework.\n' +
977
+ ' in Kitchen (at **)',
978
+ ]);
979
+
980
expect(root).toMatchRenderedOutput('apple carrot');
981
982
// Update the state variable after the use().
@@ -945,6 +991,13 @@ describe('ReactUse', () => {
991
resolveTextRequests('apple');
992
});
993
assertLog(['Async text requested [apple]', 'apple dill']);
994
+ assertConsoleErrorDev([
995
+ 'A component was suspended by an uncached promise. ' +
996
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
997
+ 'except via a Suspense-compatible library or framework.\n' +
998
+ ' in Kitchen (at **)',
999
+ ]);
1000
+
1001
expect(root).toMatchRenderedOutput('apple dill');
1002
1003
// Update the state variable before the use(). The second state is maintained.
@@ -959,6 +1012,12 @@ describe('ReactUse', () => {
1012
resolveTextRequests('banana');
1013
});
1014
assertLog(['Async text requested [banana]', 'banana dill']);
1015
+ assertConsoleErrorDev([
1016
+ 'A component was suspended by an uncached promise. ' +
1017
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1018
+ 'except via a Suspense-compatible library or framework.\n' +
1019
+ ' in Kitchen (at **)',
1020
+ ]);
1021
expect(root).toMatchRenderedOutput('banana dill');
1022
});
1023
@@ -987,6 +1046,12 @@ describe('ReactUse', () => {
1046
resolveTextRequests('aguacate');
1047
});
1048
assertLog(['Async text requested [aguacate]', 'aguacate abogado']);
1049
+ assertConsoleErrorDev([
1050
+ 'A component was suspended by an uncached promise. ' +
1051
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1052
+ 'except via a Suspense-compatible library or framework.\n' +
1053
+ ' in Lexicon (at **)',
1054
+ ]);
1055
expect(root).toMatchRenderedOutput('aguacate abogado');
1056
1057
// Now update the state.
@@ -1001,6 +1066,12 @@ describe('ReactUse', () => {
1066
resolveTextRequests('aguacate');
1067
});
1068
assertLog(['Async text requested [aguacate]', 'aguacate avocat']);
1069
+ assertConsoleErrorDev([
1070
+ 'A component was suspended by an uncached promise. ' +
1071
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1072
+ 'except via a Suspense-compatible library or framework.\n' +
1073
+ ' in Lexicon (at **)',
1074
+ ]);
1075
expect(root).toMatchRenderedOutput('aguacate avocat');
1076
});
1077
@@ -1141,6 +1212,13 @@ describe('ReactUse', () => {
1212
'Async text requested [B]',
1213
'(Loading B...)',
1214
]);
1215
+ assertConsoleErrorDev([
1216
+ 'A component was suspended by an uncached promise. ' +
1217
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1218
+ 'except via a Suspense-compatible library or framework.\n' +
1219
+ ' in AsyncText (at **)\n' +
1220
+ ' in Suspense (at **)',
1221
+ ]);
1222
expect(root).toMatchRenderedOutput('A(Loading B...)');
1223
1224
await act(() => {
@@ -1161,6 +1239,14 @@ describe('ReactUse', () => {
1239
'Async text requested [C]',
1240
'(Loading C...)',
1241
]);
1242
+ assertConsoleErrorDev([
1243
+ 'A component was suspended by an uncached promise. ' +
1244
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1245
+ 'except via a Suspense-compatible library or framework.\n' +
1246
+ ' in AsyncText (at **)\n' +
1247
+ ' in Suspense (at **)\n' +
1248
+ ' in Suspense (at **)',
1249
+ ]);
1250
expect(root).toMatchRenderedOutput('AB(Loading C...)');
1251
1252
await act(() => {
@@ -1173,6 +1259,15 @@ describe('ReactUse', () => {
1259
resolveTextRequests('C');
1260
});
1261
assertLog(['Async text requested [C]', 'C']);
1262
+ assertConsoleErrorDev([
1263
+ 'A component was suspended by an uncached promise. ' +
1264
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1265
+ 'except via a Suspense-compatible library or framework.\n' +
1266
+ ' in AsyncText (at **)\n' +
1267
+ ' in Suspense (at **)\n' +
1268
+ ' in Suspense (at **)\n' +
1269
+ ' in Suspense (at **)',
1270
+ ]);
1271
expect(root).toMatchRenderedOutput('ABC');
1272
});
1273
@@ -1202,6 +1297,22 @@ describe('ReactUse', () => {
1297
});
1298
});
1299
assertLog(['A1']);
1300
+ assertConsoleErrorDev([
1301
+ 'A component was suspended by an uncached promise. ' +
1302
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1303
+ 'except via a Suspense-compatible library or framework.\n' +
1304
+ (gate('enableOwnerStacks')
1305
+ ? ''
1306
+ : ' in Async (at **)\n' + ' in Suspense (at **)\n') +
1307
+ ' in App (at **)',
1308
+ 'A component was suspended by an uncached promise. ' +
1309
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1310
+ 'except via a Suspense-compatible library or framework.\n' +
1311
+ (gate('enableOwnerStacks')
1312
+ ? ''
1313
+ : ' in Async (at **)\n' + ' in Suspense (at **)\n') +
1314
+ ' in App (at **)',
1315
+ ]);
1316
expect(root).toMatchRenderedOutput('A1');
1317
});
1318
@@ -1231,7 +1342,12 @@ describe('ReactUse', () => {
1342
});
1343
});
1344
assertLog(['Async text requested [Hi]']);
1234
-
1345
+ assertConsoleErrorDev([
1346
+ 'async/await is not yet supported in Client Components, only Server Components. ' +
1347
+ "This error is often caused by accidentally adding `'use client'` " +
1348
+ 'to a module that was originally written for the server.\n' +
1349
+ ' in App (at **)',
1350
+ ]);
1351
await act(() => resolveTextRequests('Hi'));
1352
assertLog([
1353
// TODO: We shouldn't have to replay the function body again. Skip
@@ -1239,6 +1355,12 @@ describe('ReactUse', () => {
1355
'Async text requested [Hi]',
1356
'Hi',
1357
]);
1358
+ assertConsoleErrorDev([
1359
+ 'A component was suspended by an uncached promise. ' +
1360
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1361
+ 'except via a Suspense-compatible library or framework.\n' +
1362
+ ' in App (at **)',
1363
+ ]);
1364
expect(root).toMatchRenderedOutput('Hi');
1365
});
1366
@@ -1268,6 +1390,12 @@ describe('ReactUse', () => {
1390
'Async text requested [Hi]',
1391
'Hi',
1392
]);
1393
+ assertConsoleErrorDev([
1394
+ 'A component was suspended by an uncached promise. ' +
1395
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1396
+ 'except via a Suspense-compatible library or framework.\n' +
1397
+ ' in App (at **)',
1398
+ ]);
1399
expect(root).toMatchRenderedOutput('Hi');
1400
});
1401
@@ -1314,6 +1442,16 @@ describe('ReactUse', () => {
1442
});
1443
});
1444
assertLog(['A', 'Mount: A']);
1445
+ assertConsoleErrorDev([
1446
+ 'async/await is not yet supported in Client Components, only Server Components. ' +
1447
+ "This error is often caused by accidentally adding `'use client'` " +
1448
+ 'to a module that was originally written for the server.\n' +
1449
+ ' in App (at **)',
1450
+ 'A component was suspended by an uncached promise. ' +
1451
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1452
+ 'except via a Suspense-compatible library or framework.\n' +
1453
+ ' in App (at **)',
1454
+ ]);
1455
expect(root).toMatchRenderedOutput('A');
1456
1457
// Update the child's props. It should not remount.
@@ -1323,6 +1461,12 @@ describe('ReactUse', () => {
1461
});
1462
});
1463
assertLog(['B', 'Mount: B']);
1464
+ assertConsoleErrorDev([
1465
+ 'A component was suspended by an uncached promise. ' +
1466
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1467
+ 'except via a Suspense-compatible library or framework.\n' +
1468
+ ' in App (at **)',
1469
+ ]);
1470
expect(root).toMatchRenderedOutput('B');
1471
});
1472
@@ -1535,6 +1679,16 @@ describe('ReactUse', () => {
1679
});
1680
});
1681
assertLog(['Async']);
1682
+ assertConsoleErrorDev([
1683
+ 'A component was suspended by an uncached promise. ' +
1684
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1685
+ 'except via a Suspense-compatible library or framework.\n' +
1686
+ (gate('enableOwnerStacks')
1687
+ ? ''
1688
+ : ' in **/ReactUse-test.js:**:** (at **)\n' +
1689
+ ' in Suspense (at **)\n') +
1690
+ ' in App (at **)',
1691
+ ]);
1692
expect(root).toMatchRenderedOutput('Async');
1693
expect(ref.current).toBe(asyncInstance);
1694
});
@@ -1563,6 +1717,16 @@ describe('ReactUse', () => {
1717
});
1718
});
1719
assertLog(['Async']);
1720
+ assertConsoleErrorDev([
1721
+ 'A component was suspended by an uncached promise. ' +
1722
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1723
+ 'except via a Suspense-compatible library or framework.\n' +
1724
+ (gate('enableOwnerStacks')
1725
+ ? ''
1726
+ : ' in **/ReactUse-test.js:**:** (at **)\n' +
1727
+ ' in Suspense (at **)\n') +
1728
+ ' in App (at **)',
1729
+ ]);
1730
expect(root).toMatchRenderedOutput('Async');
1731
1732
// Update to the same value
@@ -1582,6 +1746,16 @@ describe('ReactUse', () => {
1746
});
1747
});
1748
assertLog(['Async!']);
1749
+ assertConsoleErrorDev([
1750
+ 'A component was suspended by an uncached promise. ' +
1751
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1752
+ 'except via a Suspense-compatible library or framework.\n' +
1753
+ (gate('enableOwnerStacks')
1754
+ ? ''
1755
+ : ' in **/ReactUse-test.js:**:** (at **)\n' +
1756
+ ' in Suspense (at **)\n') +
1757
+ ' in App (at **)',
1758
+ ]);
1759
expect(root).toMatchRenderedOutput('Async!');
1760
});
1761
@@ -1631,6 +1805,41 @@ describe('ReactUse', () => {
1805
});
1806
});
1807
assertLog(['Async (function component)', 'Async (memo component)']);
1808
+ assertConsoleErrorDev([
1809
+ 'ContextProvider uses the legacy childContextTypes API which will soon be removed. ' +
1810
+ 'Use React.createContext() instead. (https://react.dev/link/legacy-context)\n' +
1811
+ (gate('enableOwnerStacks') ? '' : ' in ContextProvider (at **)\n') +
1812
+ ' in App (at **)',
1813
+ 'Async uses the legacy contextTypes API which will be removed soon. ' +
1814
+ 'Use React.createContext() with React.useContext() instead. (https://react.dev/link/legacy-context)\n' +
1815
+ (gate('enableOwnerStacks')
1816
+ ? ''
1817
+ : ' in Async (at **)\n' +
1818
+ ' in div (at **)\n' +
1819
+ ' in Suspense (at **)\n' +
1820
+ ' in ContextProvider (at **)\n') +
1821
+ ' in App (at **)',
1822
+ 'A component was suspended by an uncached promise. ' +
1823
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1824
+ 'except via a Suspense-compatible library or framework.\n' +
1825
+ (gate('enableOwnerStacks')
1826
+ ? ''
1827
+ : ' in Async (at **)\n' +
1828
+ ' in div (at **)\n' +
1829
+ ' in Suspense (at **)\n' +
1830
+ ' in ContextProvider (at **)\n') +
1831
+ ' in App (at **)',
1832
+ 'A component was suspended by an uncached promise. ' +
1833
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
1834
+ 'except via a Suspense-compatible library or framework.\n' +
1835
+ (gate('enableOwnerStacks')
1836
+ ? ''
1837
+ : ' in Async (at **)\n' +
1838
+ ' in div (at **)\n' +
1839
+ ' in Suspense (at **)\n' +
1840
+ ' in ContextProvider (at **)\n') +
1841
+ ' in App (at **)',
1842
+ ]);
1843
expect(root).toMatchRenderedOutput(
1844
<>
1845
<div>Async (function component)</div>
@@ -1698,19 +1907,19 @@ describe('ReactUse', () => {
1907
}
1908
1909
const root = ReactNoop.createRoot();
1701
- await expect(async () => {
1702
- await act(() => {
1703
- root.render(
1704
- <ErrorBoundary>
1705
- <AsyncClientComponent />
1706
- </ErrorBoundary>,
1707
- );
1708
- });
1709
- }).toErrorDev([
1710
- 'async/await is not yet supported in Client Components, only ' +
1711
- 'Server Components. This error is often caused by accidentally ' +
1712
- "adding `'use client'` to a module that was originally written " +
1713
- 'for the server.',
1910
+ await act(async () => {
1911
+ root.render(
1912
+ <ErrorBoundary>
1913
+ <AsyncClientComponent />
1914
+ </ErrorBoundary>,
1915
+ );
1916
+ });
1917
+ assertConsoleErrorDev([
1918
+ 'async/await is not yet supported in Client Components, only Server Components. ' +
1919
+ "This error is often caused by accidentally adding `'use client'` " +
1920
+ 'to a module that was originally written for the server.\n' +
1921
+ ' in AsyncClientComponent (at **)' +
1922
+ (gate('enableOwnerStacks') ? '' : '\n in ErrorBoundary (at **)'),
1923
]);
1924
assertLog([
1925
'async/await is not yet supported in Client Components, only Server ' +
@@ -1750,19 +1959,19 @@ describe('ReactUse', () => {
1959
}
1960
1961
const root = ReactNoop.createRoot();
1753
- await expect(async () => {
1754
- await act(() => {
1755
- root.render(
1756
- <ErrorBoundary>
1757
- <AsyncClientComponent />
1758
- </ErrorBoundary>,
1759
- );
1760
- });
1761
- }).toErrorDev([
1762
- 'async/await is not yet supported in Client Components, only ' +
1763
- 'Server Components. This error is often caused by accidentally ' +
1764
- "adding `'use client'` to a module that was originally written " +
1765
- 'for the server.',
1962
+ await act(async () => {
1963
+ root.render(
1964
+ <ErrorBoundary>
1965
+ <AsyncClientComponent />
1966
+ </ErrorBoundary>,
1967
+ );
1968
+ });
1969
+ assertConsoleErrorDev([
1970
+ 'async/await is not yet supported in Client Components, only Server Components. ' +
1971
+ "This error is often caused by accidentally adding `'use client'` " +
1972
+ 'to a module that was originally written for the server.\n' +
1973
+ ' in AsyncClientComponent (at **)' +
1974
+ (gate('enableOwnerStacks') ? '' : '\n in ErrorBoundary (at **)'),
1975
]);
1976
assertLog([
1977
'async/await is not yet supported in Client Components, only Server ' +
@@ -1792,25 +2001,25 @@ describe('ReactUse', () => {
2001
}
2002
2003
const root = ReactNoop.createRoot();
1795
- await expect(async () => {
1796
- await act(() => {
1797
- startTransition(() => {
1798
- root.render(<AsyncClientComponent />);
1799
- });
2004
+ await act(() => {
2005
+ startTransition(() => {
2006
+ root.render(<AsyncClientComponent />);
2007
});
1801
- }).toErrorDev([
2008
+ });
2009
+ assertConsoleErrorDev([
2010
// Note: This used to log a different warning about not using hooks
2011
// inside async components, like we do on the server. Since then, we
2012
// decided to warn for _any_ async client component regardless of
2013
// whether the update is sync. But if we ever add back support for async
2014
// client components, we should add back the hook warning.
1807
- 'async/await is not yet supported in Client Components, only Server ' +
1808
- 'Components. This error is often caused by accidentally adding ' +
1809
- "`'use client'` to a module that was originally written for " +
1810
- 'the server.',
1811
- 'A component was suspended by an uncached promise. Creating ' +
1812
- 'promises inside a Client Component or hook is not yet ' +
1813
- 'supported, except via a Suspense-compatible library or framework.',
2015
+ 'async/await is not yet supported in Client Components, only Server Components. ' +
2016
+ "This error is often caused by accidentally adding `'use client'` " +
2017
+ 'to a module that was originally written for the server.\n' +
2018
+ ' in AsyncClientComponent (at **)',
2019
+ 'A component was suspended by an uncached promise. ' +
2020
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
2021
+ 'except via a Suspense-compatible library or framework.\n' +
2022
+ ' in AsyncClientComponent (at **)',
2023
]);
2024
},
2025
);
@@ -1824,28 +2033,29 @@ describe('ReactUse', () => {
2033
}
2034
2035
const root = ReactNoop.createRoot();
1827
- await expect(async () => {
1828
- await act(() => {
1829
- startTransition(() => {
1830
- root.render(<AsyncClientComponent />);
1831
- });
2036
+ await act(() => {
2037
+ startTransition(() => {
2038
+ root.render(<AsyncClientComponent />);
2039
});
1833
- }).toErrorDev([
2040
+ });
2041
+ assertConsoleErrorDev([
2042
// Note: This used to log a different warning about not using hooks
2043
// inside async components, like we do on the server. Since then, we
2044
// decided to warn for _any_ async client component regardless of
2045
// whether the update is sync. But if we ever add back support for async
2046
// client components, we should add back the hook warning.
1839
- 'async/await is not yet supported in Client Components, only Server ' +
1840
- 'Components. This error is often caused by accidentally adding ' +
1841
- "`'use client'` to a module that was originally written for " +
1842
- 'the server.',
1843
- 'A component was suspended by an uncached promise. Creating ' +
1844
- 'promises inside a Client Component or hook is not yet ' +
1845
- 'supported, except via a Suspense-compatible library or framework.',
1846
- 'A component was suspended by an uncached promise. Creating ' +
1847
- 'promises inside a Client Component or hook is not yet ' +
1848
- 'supported, except via a Suspense-compatible library or framework.',
2047
+ 'async/await is not yet supported in Client Components, only Server Components. ' +
2048
+ "This error is often caused by accidentally adding `'use client'` " +
2049
+ 'to a module that was originally written for the server.\n' +
2050
+ ' in AsyncClientComponent (at **)',
2051
+ 'A component was suspended by an uncached promise. ' +
2052
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
2053
+ 'except via a Suspense-compatible library or framework.\n' +
2054
+ ' in AsyncClientComponent (at **)',
2055
+ 'A component was suspended by an uncached promise. ' +
2056
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
2057
+ 'except via a Suspense-compatible library or framework.\n' +
2058
+ ' in AsyncClientComponent (at **)',
2059
]);
2060
});
2061
@@ -1863,38 +2073,41 @@ describe('ReactUse', () => {
2073
}
2074
2075
const root = ReactNoop.createRoot();
1866
- await expect(async () => {
1867
- await act(() => {
1868
- startTransition(() => {
1869
- root.render(<App />);
1870
- });
2076
+ await act(() => {
2077
+ startTransition(() => {
2078
+ root.render(<App />);
2079
});
1872
- }).toErrorDev([
1873
- 'async/await is not yet supported in Client Components, only ' +
1874
- 'Server Components. This error is often caused by accidentally ' +
1875
- "adding `'use client'` to a module that was originally written " +
1876
- 'for the server.',
2080
+ });
2081
+ assertConsoleErrorDev([
2082
+ 'async/await is not yet supported in Client Components, only Server Components. ' +
2083
+ "This error is often caused by accidentally adding `'use client'` " +
2084
+ 'to a module that was originally written for the server.\n' +
2085
+ ' in App (at **)',
2086
]);
2087
assertLog(['Async text requested [Hi]']);
2088
1880
- await expect(async () => {
1881
- await act(() => resolveTextRequests('Hi'));
1882
- }).toErrorDev([
2089
+ await act(() => resolveTextRequests('Hi'));
2090
+ assertConsoleErrorDev([
2091
// We get this warning because the generator's promise themselves are not cached.
1884
- 'A component was suspended by an uncached promise. Creating ' +
1885
- 'promises inside a Client Component or hook is not yet ' +
1886
- 'supported, except via a Suspense-compatible library or framework.',
2092
+ 'A component was suspended by an uncached promise. ' +
2093
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
2094
+ 'except via a Suspense-compatible library or framework.\n' +
2095
+ ' in App (at **)',
2096
]);
2097
2098
assertLog(['Async text requested [World]']);
2099
1891
- if (gate('enableSiblingPrerendering')) {
1892
- await expect(async () => {
1893
- await act(() => resolveTextRequests('World'));
1894
- }).toErrorDev(['A component was suspended by an uncached promise.']);
1895
- } else {
1896
- await act(() => resolveTextRequests('World'));
1897
- }
2100
+ await act(() => resolveTextRequests('World'));
2101
+ assertConsoleErrorDev(
2102
+ gate('enableSiblingPrerendering')
2103
+ ? [
2104
+ 'A component was suspended by an uncached promise. ' +
2105
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
2106
+ 'except via a Suspense-compatible library or framework.\n' +
2107
+ ' in App (at **)',
2108
+ ]
2109
+ : [],
2110
+ );
2111
2112
assertLog(['Hi', 'World']);
2113
expect(root).toMatchRenderedOutput('Hi World');
@@ -1928,24 +2141,30 @@ describe('ReactUse', () => {
2141
});
2142
assertLog(['Async text requested [Hi]']);
2143
1931
- await expect(async () => {
1932
- await act(() => resolveTextRequests('Hi'));
1933
- }).toErrorDev([
2144
+ await act(() => resolveTextRequests('Hi'));
2145
+ assertConsoleErrorDev([
2146
// We get this warning because the generator's promise themselves are not cached.
1935
- 'A component was suspended by an uncached promise. Creating ' +
1936
- 'promises inside a Client Component or hook is not yet ' +
1937
- 'supported, except via a Suspense-compatible library or framework.',
2147
+ 'A component was suspended by an uncached promise. ' +
2148
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
2149
+ 'except via a Suspense-compatible library or framework.\n' +
2150
+ ' in div (at **)\n' +
2151
+ ' in App (at **)',
2152
]);
2153
2154
assertLog(['Async text requested [World]']);
2155
1942
- if (gate('enableSiblingPrerendering')) {
1943
- await expect(async () => {
1944
- await act(() => resolveTextRequests('World'));
1945
- }).toErrorDev(['A component was suspended by an uncached promise.']);
1946
- } else {
1947
- await act(() => resolveTextRequests('World'));
1948
- }
2156
+ await act(() => resolveTextRequests('World'));
2157
+ assertConsoleErrorDev(
2158
+ gate('enableSiblingPrerendering')
2159
+ ? [
2160
+ 'A component was suspended by an uncached promise. ' +
2161
+ 'Creating promises inside a Client Component or hook is not yet supported, ' +
2162
+ 'except via a Suspense-compatible library or framework.\n' +
2163
+ ' in div (at **)\n' +
2164
+ ' in App (at **)',
2165
+ ]
2166
+ : [],
2167
+ );
2168
2169
assertLog(['Hi', 'World']);
2170
expect(root).toMatchRenderedOutput(<div>Hi World</div>);