Skip to content

Commit 4341ad3

Browse files
[v14] refactor: use async act by default (#1848)
1 parent 71a3312 commit 4341ad3

File tree

13 files changed

+266
-82
lines changed

13 files changed

+266
-82
lines changed

src/__tests__/react-native-gesture-handler.test.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,9 @@ test('userEvent can invoke press events for RNGH Pressable', async () => {
5757

5858
const pressable = screen.getByTestId('pressable');
5959
await user.press(pressable);
60-
expect(getEventsNames(events)).toEqual(['pressIn', 'pressOut', 'press']);
60+
61+
const eventSequence = getEventsNames(events).join(', ');
62+
expect(
63+
eventSequence === 'pressIn, pressOut, press' || eventSequence === 'pressIn, press, pressOut',
64+
).toBe(true);
6165
});

src/act.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ function withGlobalActEnvironment(actImplementation: ReactAct) {
6666
};
6767
}
6868

69-
const act = withGlobalActEnvironment(reactAct) as ReactAct;
69+
export const unsafe_act = withGlobalActEnvironment(reactAct) as ReactAct;
70+
71+
export function act<T>(callback: () => T | Promise<T>): Promise<T> {
72+
return unsafe_act(async () => await callback());
73+
}
7074

71-
export default act;
7275
export { getIsReactActEnvironment, setIsReactActEnvironment as setReactActEnvironment };

src/fire-event.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type {
77
} from 'react-native';
88
import type { Fiber, HostElement } from 'universal-test-renderer';
99

10-
import act from './act';
10+
import { act, unsafe_act } from './act';
1111
import type { EventHandler } from './event-handler';
1212
import { getEventHandlerFromProps } from './event-handler';
1313
import { isElementMounted, isHostElement } from './helpers/component-tree';
@@ -139,8 +139,7 @@ async function fireEvent(element: HostElement, eventName: EventName, ...data: un
139139
}
140140

141141
let returnValue;
142-
// eslint-disable-next-line require-await
143-
await act(async () => {
142+
await act(() => {
144143
returnValue = handler(...data);
145144
});
146145

@@ -170,7 +169,7 @@ function unsafe_fireEventSync(element: HostElement, eventName: EventName, ...dat
170169
}
171170

172171
let returnValue;
173-
void act(() => {
172+
void unsafe_act(() => {
174173
returnValue = handler(...data);
175174
});
176175

src/pure.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export { default as act } from './act';
1+
export { act, unsafe_act } from './act';
22
export { cleanup } from './cleanup';
33
export { fireEvent, unsafe_fireEventSync } from './fire-event';
44
export { render } from './render';

src/render-act.ts

Lines changed: 0 additions & 29 deletions
This file was deleted.

src/render.tsx

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import * as React from 'react';
2-
import type { HostElement, JsonElement, Root, RootOptions } from 'universal-test-renderer';
3-
4-
import act from './act';
2+
import {
3+
createRoot,
4+
type HostElement,
5+
type JsonElement,
6+
type Root,
7+
type RootOptions,
8+
} from 'universal-test-renderer';
9+
10+
import { act } from './act';
511
import { addToCleanupQueue } from './cleanup';
612
import { getConfig } from './config';
713
import type { DebugOptions } from './helpers/debug';
814
import { debug } from './helpers/debug';
915
import { HOST_TEXT_NAMES } from './helpers/host-component-names';
10-
import { renderWithAsyncAct } from './render-act';
1116
import { setRenderResult } from './screen';
1217
import { getQueriesForElement } from './within';
1318

@@ -28,7 +33,7 @@ export type RenderResult = Awaited<ReturnType<typeof render>>;
2833
* Renders test component deeply using React Test Renderer and exposes helpers
2934
* to assert on the output.
3035
*/
31-
export async function render<T>(component: React.ReactElement<T>, options: RenderOptions = {}) {
36+
export async function render<T>(element: React.ReactElement<T>, options: RenderOptions = {}) {
3237
const { wrapper: Wrapper, createNodeMock } = options || {};
3338

3439
const rendererOptions: RootOptions = {
@@ -37,26 +42,22 @@ export async function render<T>(component: React.ReactElement<T>, options: Rende
3742
};
3843

3944
const wrap = (element: React.ReactElement) => (Wrapper ? <Wrapper>{element}</Wrapper> : element);
40-
const renderer = await renderWithAsyncAct(wrap(component), rendererOptions);
41-
return buildRenderResult(renderer, wrap);
42-
}
45+
const renderer = createRoot(rendererOptions);
46+
47+
await act(() => {
48+
renderer.render(wrap(element));
49+
});
4350

44-
function buildRenderResult(
45-
renderer: Root,
46-
wrap: (element: React.ReactElement) => React.JSX.Element,
47-
) {
4851
const container = renderer.container;
4952

5053
const rerender = async (component: React.ReactElement) => {
51-
// eslint-disable-next-line require-await
52-
await act(async () => {
54+
await act(() => {
5355
renderer.render(wrap(component));
5456
});
5557
};
5658

5759
const unmount = async () => {
58-
// eslint-disable-next-line require-await
59-
await act(async () => {
60+
await act(() => {
6061
renderer.unmount();
6162
});
6263
};

src/unsafe-render-sync.tsx

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import * as React from 'react';
2-
import type { HostElement, JsonElement, Root, RootOptions } from 'universal-test-renderer';
3-
4-
import act from './act';
2+
import {
3+
createRoot,
4+
type HostElement,
5+
type JsonElement,
6+
type Root,
7+
type RootOptions,
8+
} from 'universal-test-renderer';
9+
10+
import { act, unsafe_act } from './act';
511
import { addToCleanupQueue } from './cleanup';
612
import { getConfig } from './config';
713
import type { DebugOptions } from './helpers/debug';
814
import { debug } from './helpers/debug';
915
import { HOST_TEXT_NAMES } from './helpers/host-component-names';
10-
import { renderWithAct } from './render-act';
1116
import { setRenderResult } from './screen';
1217
import { getQueriesForElement } from './within';
1318

@@ -45,36 +50,33 @@ export function renderInternal<T>(component: React.ReactElement<T>, options?: Re
4550
};
4651

4752
const wrap = (element: React.ReactElement) => (Wrapper ? <Wrapper>{element}</Wrapper> : element);
48-
const renderer = renderWithAct(wrap(component), rendererOptions);
49-
return buildRenderResult(renderer, wrap);
50-
}
5153

52-
function buildRenderResult(
53-
renderer: Root,
54-
wrap: (element: React.ReactElement) => React.JSX.Element,
55-
) {
54+
const renderer = createRoot(rendererOptions);
55+
56+
unsafe_act(() => {
57+
renderer.render(wrap(component));
58+
});
59+
5660
const rerender = (component: React.ReactElement) => {
57-
void act(() => {
61+
unsafe_act(() => {
5862
renderer.render(wrap(component));
5963
});
6064
};
6165

6266
const rerenderAsync = async (component: React.ReactElement) => {
63-
// eslint-disable-next-line require-await
64-
await act(async () => {
67+
await act(() => {
6568
renderer.render(wrap(component));
6669
});
6770
};
6871

6972
const unmount = () => {
70-
void act(() => {
73+
unsafe_act(() => {
7174
renderer.unmount();
7275
});
7376
};
7477

7578
const unmountAsync = async () => {
76-
// eslint-disable-next-line require-await
77-
await act(async () => {
79+
await act(() => {
7880
renderer.unmount();
7981
});
8082
};

src/user-event/press/press.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { HostElement } from 'universal-test-renderer';
22

3-
import act from '../../act';
3+
import { act } from '../../act';
44
import { getEventHandlerFromProps } from '../../event-handler';
55
import { isHostElement } from '../../helpers/component-tree';
66
import { ErrorWithStack } from '../../helpers/errors';

src/user-event/utils/dispatch-event.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { HostElement } from 'universal-test-renderer';
22

3-
import act from '../../act';
3+
import { act } from '../../act';
44
import { getEventHandlerFromProps } from '../../event-handler';
55
import { isElementMounted } from '../../helpers/component-tree';
66

@@ -21,8 +21,7 @@ export async function dispatchEvent(element: HostElement, eventName: string, ...
2121
return;
2222
}
2323

24-
// eslint-disable-next-line require-await
25-
await act(async () => {
24+
await act(() => {
2625
handler(...event);
2726
});
2827
}

src/wait-for.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* globals jest */
2-
import act from './act';
2+
import { act } from './act';
33
import { getConfig } from './config';
44
import { flushMicroTasks } from './flush-micro-tasks';
55
import { copyStackTrace, ErrorWithStack } from './helpers/errors';
@@ -70,7 +70,7 @@ function waitForInternal<T>(
7070
// third party code that's setting up recursive timers so rapidly that
7171
// the user's timer's don't get a chance to resolve. So we'll advance
7272
// by an interval instead. (We have a test for this case).
73-
await act(async () => await jest.advanceTimersByTime(interval));
73+
await act(() => jest.advanceTimersByTime(interval));
7474

7575
// It's really important that checkExpectation is run *before* we flush
7676
// in-flight promises. To be honest, I'm not sure why, and I can't quite

0 commit comments

Comments
 (0)