Skip to content

Commit 6b67a76

Browse files
committed
Codemod act -> await act (4/?)
Similar to the rationale for `waitFor` (see facebook#26285), we should always await the result of an `act` call so that microtasks have a chance to fire. This only affects the internal `act` that we use in our repo, for now. In the public `act` API, we don't yet require this; however, we effectively will for any update that triggers suspense once `use` lands. So we likely will start warning in an upcoming minor.
1 parent 161f6ae commit 6b67a76

17 files changed

+812
-999
lines changed

packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ describe('ReactHooksInspectionIntegration', () => {
984984
children: ['count: ', '1'],
985985
});
986986

987-
act(incrementCount);
987+
await act(async () => incrementCount());
988988
expect(renderer.toJSON()).toEqual({
989989
type: 'div',
990990
props: {},

packages/react-devtools-shared/src/__tests__/inspectedElement-test.js

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,8 +1069,8 @@ describe('InspectedElement', () => {
10691069
});
10701070

10711071
async function loadPath(path) {
1072-
TestUtilsAct(() => {
1073-
TestRendererAct(() => {
1072+
await TestUtilsAct(async () => {
1073+
await TestRendererAct(async () => {
10741074
inspectElementPath(path);
10751075
jest.runOnlyPendingTimers();
10761076
});
@@ -1224,8 +1224,8 @@ describe('InspectedElement', () => {
12241224
});
12251225

12261226
async function loadPath(path) {
1227-
TestUtilsAct(() => {
1228-
TestRendererAct(() => {
1227+
await TestUtilsAct(async () => {
1228+
await TestRendererAct(async () => {
12291229
inspectElementPath(path);
12301230
jest.runOnlyPendingTimers();
12311231
});
@@ -1306,8 +1306,8 @@ describe('InspectedElement', () => {
13061306
});
13071307

13081308
async function loadPath(path) {
1309-
TestUtilsAct(() => {
1310-
TestRendererAct(() => {
1309+
await TestUtilsAct(async () => {
1310+
await TestRendererAct(async () => {
13111311
inspectElementPath(path);
13121312
jest.runOnlyPendingTimers();
13131313
});
@@ -1375,8 +1375,8 @@ describe('InspectedElement', () => {
13751375
}
13761376
`);
13771377

1378-
TestRendererAct(() => {
1379-
TestUtilsAct(() => {
1378+
await TestRendererAct(async () => {
1379+
await TestUtilsAct(async () => {
13801380
legacyRender(
13811381
<Example
13821382
nestedObject={{
@@ -1469,8 +1469,8 @@ describe('InspectedElement', () => {
14691469
});
14701470

14711471
async function loadPath(path) {
1472-
TestUtilsAct(() => {
1473-
TestRendererAct(() => {
1472+
await TestUtilsAct(async () => {
1473+
await TestRendererAct(async () => {
14741474
inspectElementPath(path);
14751475
jest.runOnlyPendingTimers();
14761476
});
@@ -1513,8 +1513,8 @@ describe('InspectedElement', () => {
15131513
}
15141514
`);
15151515

1516-
TestRendererAct(() => {
1517-
TestUtilsAct(() => {
1516+
await TestRendererAct(async () => {
1517+
await TestUtilsAct(async () => {
15181518
legacyRender(
15191519
<Example
15201520
nestedObject={{
@@ -1596,8 +1596,8 @@ describe('InspectedElement', () => {
15961596
});
15971597

15981598
async function loadPath(path) {
1599-
TestUtilsAct(() => {
1600-
TestRendererAct(() => {
1599+
await TestUtilsAct(async () => {
1600+
await TestRendererAct(async () => {
16011601
inspectElementPath(path);
16021602
jest.runOnlyPendingTimers();
16031603
});
@@ -1618,7 +1618,7 @@ describe('InspectedElement', () => {
16181618
}
16191619
`);
16201620

1621-
TestUtilsAct(() => {
1621+
await TestUtilsAct(async () => {
16221622
legacyRender(
16231623
<Example
16241624
nestedObject={{
@@ -1640,11 +1640,9 @@ describe('InspectedElement', () => {
16401640
expect(inspectedElement.props).toMatchInlineSnapshot(`
16411641
{
16421642
"nestedObject": {
1643-
"a": {
1644-
"b": {
1645-
"value": 2,
1646-
},
1647-
"value": 2,
1643+
"a": Dehydrated {
1644+
"preview_short": {…},
1645+
"preview_long": {b: {…}, value: 2},
16481646
},
16491647
"value": 2,
16501648
},
@@ -2833,7 +2831,7 @@ describe('InspectedElement', () => {
28332831
};
28342832
const toggleError = async forceError => {
28352833
await withErrorsOrWarningsIgnored(['ErrorBoundary'], async () => {
2836-
await TestUtilsAct(() => {
2834+
await TestUtilsAct(async () => {
28372835
bridge.send('overrideError', {
28382836
id: targetErrorBoundaryID,
28392837
rendererID: store.getRendererIDForElement(targetErrorBoundaryID),
@@ -2842,7 +2840,7 @@ describe('InspectedElement', () => {
28422840
});
28432841
});
28442842

2845-
TestUtilsAct(() => {
2843+
await TestUtilsAct(async () => {
28462844
jest.runOnlyPendingTimers();
28472845
});
28482846
};

packages/react-dom/src/__tests__/utils/ReactDOMServerIntegrationTestUtils.js

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,16 @@ module.exports = function (initModules) {
4848
// ====================================
4949

5050
// promisified version of ReactDOM.render()
51-
function asyncReactDOMRender(reactElement, domElement, forceHydrate) {
52-
return new Promise(resolve => {
53-
if (forceHydrate) {
54-
act(() => {
55-
ReactDOM.hydrate(reactElement, domElement);
56-
});
57-
} else {
58-
act(() => {
59-
ReactDOM.render(reactElement, domElement);
60-
});
61-
}
62-
// We can't use the callback for resolution because that will not catch
63-
// errors. They're thrown.
64-
resolve();
65-
});
51+
async function asyncReactDOMRender(reactElement, domElement, forceHydrate) {
52+
if (forceHydrate) {
53+
await act(async () => {
54+
ReactDOM.hydrate(reactElement, domElement);
55+
});
56+
} else {
57+
await act(async () => {
58+
ReactDOM.render(reactElement, domElement);
59+
});
60+
}
6661
}
6762
// performs fn asynchronously and expects count errors logged to console.error.
6863
// will fail the test if the count of errors logged is not equal to count.

packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2520,7 +2520,7 @@ describe('DOMPluginEventSystem', () => {
25202520
});
25212521

25222522
// @gate www
2523-
it('beforeblur and afterblur are called after a focused element is suspended', () => {
2523+
it('beforeblur and afterblur are called after a focused element is suspended', async () => {
25242524
const log = [];
25252525
// We have to persist here because we want to read relatedTarget later.
25262526
const onAfterBlur = jest.fn(e => {
@@ -2575,7 +2575,7 @@ describe('DOMPluginEventSystem', () => {
25752575

25762576
const root = ReactDOMClient.createRoot(container2);
25772577

2578-
act(() => {
2578+
await act(async () => {
25792579
root.render(<Component />);
25802580
});
25812581
jest.runAllTimers();
@@ -2587,7 +2587,7 @@ describe('DOMPluginEventSystem', () => {
25872587
expect(onAfterBlur).toHaveBeenCalledTimes(0);
25882588

25892589
suspend = true;
2590-
act(() => {
2590+
await act(async () => {
25912591
root.render(<Component />);
25922592
});
25932593
jest.runAllTimers();
@@ -2604,7 +2604,7 @@ describe('DOMPluginEventSystem', () => {
26042604
});
26052605

26062606
// @gate www
2607-
it('beforeblur should skip handlers from a deleted subtree after the focused element is suspended', () => {
2607+
it('beforeblur should skip handlers from a deleted subtree after the focused element is suspended', async () => {
26082608
const onBeforeBlur = jest.fn();
26092609
const innerRef = React.createRef();
26102610
const innerRef2 = React.createRef();
@@ -2661,7 +2661,7 @@ describe('DOMPluginEventSystem', () => {
26612661

26622662
const root = ReactDOMClient.createRoot(container2);
26632663

2664-
act(() => {
2664+
await act(async () => {
26652665
root.render(<Component />);
26662666
});
26672667
jest.runAllTimers();
@@ -2672,7 +2672,7 @@ describe('DOMPluginEventSystem', () => {
26722672
expect(onBeforeBlur).toHaveBeenCalledTimes(0);
26732673

26742674
suspend = true;
2675-
act(() => {
2675+
await act(async () => {
26762676
root.render(<Component />);
26772677
});
26782678
jest.runAllTimers();
@@ -2684,17 +2684,17 @@ describe('DOMPluginEventSystem', () => {
26842684
});
26852685

26862686
// @gate www
2687-
it('regression: does not fire beforeblur/afterblur if target is already hidden', () => {
2687+
it('regression: does not fire beforeblur/afterblur if target is already hidden', async () => {
26882688
const Suspense = React.Suspense;
26892689
let suspend = false;
2690-
const promise = Promise.resolve();
2690+
const fakePromise = {then() {}};
26912691
const setBeforeBlurHandle =
26922692
ReactDOM.unstable_createEventHandle('beforeblur');
26932693
const innerRef = React.createRef();
26942694

26952695
function Child() {
26962696
if (suspend) {
2697-
throw promise;
2697+
throw fakePromise;
26982698
}
26992699
return <input ref={innerRef} />;
27002700
}
@@ -2726,7 +2726,7 @@ describe('DOMPluginEventSystem', () => {
27262726
document.body.appendChild(container2);
27272727

27282728
const root = ReactDOMClient.createRoot(container2);
2729-
act(() => {
2729+
await act(async () => {
27302730
root.render(<Component />);
27312731
});
27322732

@@ -2737,7 +2737,7 @@ describe('DOMPluginEventSystem', () => {
27372737

27382738
// Suspend. This hides the input node, causing it to lose focus.
27392739
suspend = true;
2740-
act(() => {
2740+
await act(async () => {
27412741
root.render(<Component />);
27422742
});
27432743

0 commit comments

Comments
 (0)