|
1 | 1 | # React 19 & Suspense Support |
2 | 2 |
|
3 | | -React 19 introduced full support for React Suspense, `React.use()`, and other async rendering features to React Native [0.78.0](https://github.com/facebook/react-native/releases/tag/v0.78.0). These new capabilities enable more sophisticated async patterns but also require updates to testing approaches. |
| 3 | +React 19 introduced full support for React Suspense, [`React.use()`](https://react.dev/reference/react/use), and other async rendering features to React Native [0.78.0](https://github.com/facebook/react-native/releases/tag/v0.78.0). These new capabilities enable more sophisticated async patterns in your React Native apps, but they also require updates to your testing approach. |
4 | 4 |
|
5 | | -## Impact on React Rendering |
| 5 | +## Why New Testing APIs Are Needed |
6 | 6 |
|
7 | | -React 19's async rendering features make React's rendering process more asynchronous by nature. This requires the use of the [`async act`](https://react.dev/reference/react/act) helper when testing components that use these new APIs, which in turn affects several React Native Testing Library APIs. |
| 7 | +React 19's async rendering features (like Suspense and `React.use()`) make React's rendering process inherently asynchronous. When testing components that use these features, React requires the [`async act`](https://react.dev/reference/react/act) helper to properly handle async state updates. |
8 | 8 |
|
9 | | -Note that `renderAsync` and other async APIs also support React 18. |
| 9 | +This need for async handling led to the creation of new async versions of RNTL's core APIs. These async APIs work with both React 18 and React 19, making them forward-compatible choices for your test suite. |
10 | 10 |
|
11 | 11 | ## New Async APIs in RNTL 13.3 |
12 | 12 |
|
13 | | -To support React 19's async rendering, RNTL 13.3 introduces several new async APIs: |
| 13 | +RNTL 13.3 introduces async versions of the core testing APIs to handle React 19's async rendering: |
14 | 14 |
|
| 15 | +**Rendering APIs:** |
15 | 16 | - **[`renderAsync`](docs/api/render#render-async)** - async version of [`render`](docs/api/render) |
16 | | -- `screen` object |
17 | | - - **[`rerenderAsync`](docs/api/screen#rerender-async)** - async version of [`rerender`](docs/api/screen#rerender) |
18 | | - - **[`unmountAsync`](docs/api/screen#unmount-async)** - async version of [`unmount`](docs/api/screen#unmount) |
| 17 | +- **[`screen.rerenderAsync`](docs/api/screen#rerender-async)** - async version of [`screen.rerender`](docs/api/screen#rerender) |
| 18 | +- **[`screen.unmountAsync`](docs/api/screen#unmount-async)** - async version of [`screen.unmount`](docs/api/screen#unmount) |
| 19 | + |
| 20 | +**Event APIs:** |
19 | 21 | - **[`fireEventAsync`](docs/api/fire-event#fire-event-async)** - async version of [`fireEvent`](docs/api/fire-event#fire-event) |
20 | 22 |
|
21 | | -## Unchanged APIs |
| 23 | +## APIs That Remain Unchanged |
22 | 24 |
|
23 | | -Some APIs didn't require changes: |
| 25 | +Many existing APIs continue to work without modification: |
24 | 26 |
|
25 | | -- `screen` object: most of the methods, including queries |
26 | | -- **[`userEvent`](docs/api/user-event)** didn't require API changes as it was already async |
27 | | -- **Jest Matchers** didn't require any changes as they work with already processed output |
| 27 | +- **Query methods** - `screen.getBy*`, `screen.queryBy*`, `screen.findBy*` all work the same |
| 28 | +- **[`userEvent`](docs/api/user-event)** - already async, so no API changes needed |
| 29 | +- **Jest matchers** - work with already-rendered output, so no changes required |
28 | 30 |
|
29 | | -## Key Changes for Testing |
| 31 | +## What Changes in Your Tests |
30 | 32 |
|
31 | | -### Main Change: `renderAsync` |
| 33 | +### Making Tests Async |
32 | 34 |
|
33 | | -The primary change is the introduction of [`renderAsync`](docs/api/render#renderasync), which requires making your tests `async` and using the `await` keyword: |
| 35 | +The main change is using [`renderAsync`](docs/api/render#renderasync) instead of `render`, which requires: |
| 36 | +1. Making your test function `async` |
| 37 | +2. Adding `await` before `renderAsync` |
34 | 38 |
|
35 | 39 | ```tsx |
36 | | -// Before (React 18 and earlier) |
| 40 | +// Synchronous approach (React 18 pattern) |
37 | 41 | test('my component', () => { |
38 | 42 | render(<MyComponent />); |
39 | 43 | expect(screen.getByText('Hello')).toBeOnTheScreen(); |
40 | 44 | }); |
41 | 45 |
|
42 | | -// After (React 19 with Suspense) |
| 46 | +// Async approach (React 19 ready) |
43 | 47 | test('my component', async () => { |
44 | 48 | await renderAsync(<MyComponent />); |
45 | 49 | expect(screen.getByText('Hello')).toBeOnTheScreen(); |
46 | 50 | }); |
47 | 51 | ``` |
48 | 52 |
|
| 53 | +### When to Use Async APIs |
| 54 | + |
| 55 | +Use the async APIs when your components: |
| 56 | +- Use React Suspense for data fetching or code splitting |
| 57 | +- Call `React.use()` for reading promises or context |
| 58 | +- Have async state updates that need proper `act()` handling |
| 59 | + |
49 | 60 | ## Migration Strategy |
50 | 61 |
|
51 | | -While these async APIs are new in RNTL 13.3, we expect them to become the default recommendation in the future. We advise: |
| 62 | +### For New Projects |
| 63 | +Use the async APIs (`renderAsync`, User Event, etc.) from the start. They work with both React 18 and React 19, making your tests future-ready. |
52 | 64 |
|
53 | | -- **New testing code**: use the async APIs (`renderAsync`, etc.) for all new tests |
54 | | -- **Legacy testing code**: can continue using the synchronous versions (`render`, etc.) without any required changes |
| 65 | +### For Existing Projects |
| 66 | +You can migrate gradually: |
| 67 | +- **Existing tests** continue to work with synchronous APIs (`render`, etc.) |
| 68 | +- **New tests** should use async APIs |
| 69 | +- **Tests with Suspense/React.use()** must use async APIs |
55 | 70 |
|
56 | | -This approach allows for gradual migration while ensuring compatibility with both React 18 and React 19 features. |
| 71 | +### Future Direction |
| 72 | +We expect async APIs to become the default recommendation as React 19 adoption grows. Starting with async APIs now will save migration effort later. |
0 commit comments