From b96bb2bd4df567a39799ac261d7eee48104df9b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Jastrze=CC=A8bski?= Date: Mon, 11 Aug 2025 14:43:12 +0200 Subject: [PATCH 1/9] docs: suspense docs --- .../docs/13.x/docs/api/events/fire-event.mdx | 84 +++++++++++++------ .../docs/13.x/docs/api/events/user-event.mdx | 4 - website/docs/13.x/docs/api/render.mdx | 14 ++-- 3 files changed, 67 insertions(+), 35 deletions(-) diff --git a/website/docs/13.x/docs/api/events/fire-event.mdx b/website/docs/13.x/docs/api/events/fire-event.mdx index c2ab68951..d5c4297c1 100644 --- a/website/docs/13.x/docs/api/events/fire-event.mdx +++ b/website/docs/13.x/docs/api/events/fire-event.mdx @@ -1,8 +1,6 @@ # Fire Event API -```ts -function fireEvent(element: ReactTestInstance, eventName: string, ...data: unknown[]): void; -``` +## `fireEvent` {#fire-event} :::note For common events like `press` or `type` it's recommended to use [User Event API](docs/api/events/user-event) as it offers @@ -11,6 +9,10 @@ more realistic event simulation by emitting a sequence of events with proper eve Use Fire Event for cases not supported by User Event and for triggering event handlers on composite components. ::: +```ts +function fireEvent(element: ReactTestInstance, eventName: string, ...data: unknown[]): void; +``` + The `fireEvent` API allows you to trigger all kinds of event handlers on both host and composite components. It will try to invoke a single event handler traversing the component tree bottom-up from passed element and trying to find enabled event handler named `onXxx` when `xxx` is the name of the event passed. Unlike User Event, this API does not automatically pass event object to event handler, this is responsibility of the user to construct such object. @@ -57,14 +59,17 @@ FireEvent exposes convenience methods for common events like: `press`, `changeTe ### `fireEvent.press` {#press} -``` -fireEvent.press: (element: ReactTestInstance, ...data: Array) => void -``` - :::note It is recommended to use the User Event [`press()`](docs/api/events/user-event#press) helper instead as it offers more realistic simulation of press interaction, including pressable support. ::: +```tsx +fireEvent.press: ( + element: ReactTestInstance, + ...data: Array, +) => void +``` + Invokes `press` event handler on the element or parent element in the tree. ```jsx @@ -93,14 +98,17 @@ expect(onPressMock).toHaveBeenCalledWith(eventData); ### `fireEvent.changeText` {#change-text} -``` -fireEvent.changeText: (element: ReactTestInstance, ...data: Array) => void -``` - :::note It is recommended to use the User Event [`type()`](docs/api/events/user-event#type) helper instead as it offers more realistic simulation of text change interaction, including key-by-key typing, element focus, and other editing events. ::: +```tsx +fireEvent.changeText: ( + element: ReactTestInstance, + ...data: Array, +) => void +``` + Invokes `changeText` event handler on the element or parent element in the tree. ```jsx @@ -121,8 +129,15 @@ fireEvent.changeText(screen.getByPlaceholderText('Enter data'), CHANGE_TEXT); ### `fireEvent.scroll` {#scroll} -``` -fireEvent.scroll: (element: ReactTestInstance, ...data: Array) => void +:::note +Prefer using [`user.scrollTo`](docs/api/events/user-event#scrollto) over `fireEvent.scroll` for `ScrollView`, `FlatList`, and `SectionList` components. User Event provides a more realistic event simulation based on React Native runtime behavior. +::: + +```tsx +fireEvent.scroll: ( + element: ReactTestInstance, + ...data: Array, +) => void ``` Invokes `scroll` event handler on the element or parent element in the tree. @@ -152,12 +167,10 @@ fireEvent.scroll(screen.getByText('scroll-view'), eventData); ``` :::note - Prefer using [`user.scrollTo`](docs/api/events/user-event#scrollto) over `fireEvent.scroll` for `ScrollView`, `FlatList`, and `SectionList` components. User Event provides a more realistic event simulation based on React Native runtime behavior. - ::: -## `fireEventAsync` +## `fireEventAsync` {#async} :::info RNTL minimal version @@ -190,24 +203,45 @@ Like `fireEvent`, `fireEventAsync` also provides convenience methods for common ### `fireEventAsync.press` {#async-press} -``` -fireEventAsync.press: (element: ReactTestInstance, ...data: Array) => Promise +:::note +It is recommended to use the User Event [`press()`](docs/api/events/user-event#press) helper instead as it offers more realistic simulation of press interaction, including pressable support. +::: + +```tsx +fireEventAsync.press: ( + element: ReactTestInstance, + ...data: Array, +) => Promise ``` -Async version of `fireEvent.press` designed for React 19 and React Suspense. Use when press event handlers trigger suspense boundaries. +Async version of `fireEvent.press` designed for React 19 and React Suspense. Use when `press` event handlers trigger suspense boundaries. ### `fireEventAsync.changeText` {#async-change-text} -``` -fireEventAsync.changeText: (element: ReactTestInstance, ...data: Array) => Promise +:::note +It is recommended to use the User Event [`type()`](docs/api/events/user-event#type) helper instead as it offers more realistic simulation of text change interaction, including key-by-key typing, element focus, and other editing events. +::: + +```tsx +fireEventAsync.changeText: ( + element: ReactTestInstance, + ...data: Array, +) => Promise ``` -Async version of `fireEvent.changeText` designed for React 19 and React Suspense. Use when changeText event handlers trigger suspense boundaries. +Async version of `fireEvent.changeText` designed for React 19 and React Suspense. Use when `changeText` event handlers trigger suspense boundaries. ### `fireEventAsync.scroll` {#async-scroll} -``` -fireEventAsync.scroll: (element: ReactTestInstance, ...data: Array) => Promise +:::note +Prefer using [`user.scrollTo`](docs/api/events/user-event#scrollto) over `fireEventAsync.scroll` for `ScrollView`, `FlatList`, and `SectionList` components. User Event provides a more realistic event simulation based on React Native runtime behavior. +::: + +```tsx +fireEventAsync.scroll: ( + element: ReactTestInstance, + ...data: Array, +) => Promise ``` -Async version of `fireEvent.scroll` designed for React 19 and React Suspense. Use when scroll event handlers trigger suspense boundaries. +Async version of `fireEvent.scroll` designed for React 19 and React Suspense. Use when `scroll` event handlers trigger suspense boundaries. diff --git a/website/docs/13.x/docs/api/events/user-event.mdx b/website/docs/13.x/docs/api/events/user-event.mdx index f554bc53e..4684faebe 100644 --- a/website/docs/13.x/docs/api/events/user-event.mdx +++ b/website/docs/13.x/docs/api/events/user-event.mdx @@ -226,10 +226,6 @@ Events will not be emitted if the `editable` prop is set to `false`. ## `scrollTo()` \{#scroll-to} -:::note -`scrollTo` interaction has been introduced in RNTL v12.4.0. -::: - ```ts scrollTo( element: ReactTestInstance, diff --git a/website/docs/13.x/docs/api/render.mdx b/website/docs/13.x/docs/api/render.mdx index b7560e94f..b61e70028 100644 --- a/website/docs/13.x/docs/api/render.mdx +++ b/website/docs/13.x/docs/api/render.mdx @@ -1,5 +1,7 @@ # `render` function +## `render` + ```jsx function render( component: React.Element, @@ -20,11 +22,11 @@ test('basic test', () => { > When using React context providers, like Redux Provider, you'll likely want to wrap rendered component with them. In such cases, it's convenient to create your own custom `render` method. [Follow this great guide on how to set this up](https://testing-library.com/docs/react-testing-library/setup#custom-render). -## Options +### Options The behavior of the `render` method can be customized by passing various options as a second argument of the `RenderOptions` type: -### `wrapper` option +#### `wrapper` ```ts wrapper?: React.ComponentType, @@ -32,12 +34,12 @@ wrapper?: React.ComponentType, This option allows you to wrap the tested component, passed as the first option to the `render()` function, in an additional wrapper component. This is useful for creating reusable custom render functions for common React Context providers. -### `concurrentRoot` option {#concurrent-root} +#### `concurrentRoot` {#concurrent-root} Set to `false` to disable concurrent rendering. Otherwise, `render` will default to using concurrent rendering used in the React Native New Architecture. -### `createNodeMock` option +#### `createNodeMock` {#create-node-mock} ```ts createNodeMock?: (element: React.Element) => unknown, @@ -45,7 +47,7 @@ createNodeMock?: (element: React.Element) => unknown, This option allows you to pass `createNodeMock` option to `ReactTestRenderer.create()` method in order to allow for custom mock refs. You can learn more about this option from [React Test Renderer documentation](https://reactjs.org/docs/test-renderer.html#ideas). -### `unstable_validateStringsRenderedWithinText` option +#### `unstable_validateStringsRenderedWithinText` ```ts unstable_validateStringsRenderedWithinText?: boolean; @@ -59,7 +61,7 @@ This **experimental** option allows you to replicate React Native behavior of th React Test Renderer does not enforce this check; hence, by default, React Native Testing Library also does not check this. That might result in runtime errors when running your code on a device, while the code works without errors in tests. -## Result +### Result The `render` function returns the same queries and utilities as the [`screen`](docs/api/screen) object. We recommended using the `screen` object as more developer-friendly way. From d3e1246e6116428394f5cd52630a2521c56de4ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Jastrze=CC=A8bski?= Date: Mon, 11 Aug 2025 14:46:20 +0200 Subject: [PATCH 2/9] render hook --- .../docs/13.x/docs/api/misc/render-hook.mdx | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/website/docs/13.x/docs/api/misc/render-hook.mdx b/website/docs/13.x/docs/api/misc/render-hook.mdx index eab8e8562..a581ad128 100644 --- a/website/docs/13.x/docs/api/misc/render-hook.mdx +++ b/website/docs/13.x/docs/api/misc/render-hook.mdx @@ -1,5 +1,7 @@ # `renderHook` function +## `renderHook` + ```ts function renderHook( hookFn: (props?: Props) => Result, @@ -41,15 +43,15 @@ Callback is a function that is called each `render` of the test component. This The `props` passed into the callback will be the `initialProps` provided in the `options` to `renderHook`, unless new props are provided by a subsequent `rerender` call. -## `options` +### `options` A `RenderHookOptions` object to modify the execution of the `callback` function, containing the following properties: -### `initialProps` {#initial-props} +#### `initialProps` {#initial-props} The initial values to pass as `props` to the `callback` function of `renderHook`. The `Props` type is determined by the type passed to or inferred by the `renderHook` call. -### `wrapper` +#### `wrapper` A React component to wrap the test component in when rendering. This is usually used to add context providers from `React.createContext` for the hook to access with `useContext`. @@ -58,7 +60,7 @@ A React component to wrap the test component in when rendering. This is usually Set to `false` to disable concurrent rendering. Otherwise, `render` will default to using concurrent rendering used in the React Native New Architecture. -## Result +### Result ```ts interface RenderHookResult { @@ -70,23 +72,23 @@ interface RenderHookResult { The `renderHook` function returns an object that has the following properties: -### `result` +#### `result` The `current` value of the `result` will reflect the latest of whatever is returned from the `callback` passed to `renderHook`. The `Result` type is determined by the type passed to or inferred by the `renderHook` call. -### `rerender` +#### `rerender` A function to rerender the test component, causing any hooks to be recalculated. If `newProps` are passed, they will replace the `callback` function's `initialProps` for subsequent rerenders. The `Props` type is determined by the type passed to or inferred by the `renderHook` call. -### `unmount` +#### `unmount` A function to unmount the test component. This is commonly used to trigger cleanup effects for `useEffect` hooks. -## Examples +### Examples Here we present some extra examples of using `renderHook` API. -### With `initialProps` +#### With `initialProps` ```ts const useCount = (initialCount: number) => { @@ -117,7 +119,7 @@ it('should increment count', () => { }); ``` -### With `wrapper` +#### With `wrapper` ```tsx it('should use context value', () => { @@ -150,18 +152,18 @@ Async versions of `renderHook` designed for working with React 19 and React Susp ```ts interface RenderHookAsyncResult { result: { current: Result }; - rerender: (props: Props) => Promise; - unmount: () => Promise; + rerenderAsync: (props: Props) => Promise; + unmountAsync: () => Promise; } ``` -The `RenderHookAsyncResult` differs from `RenderHookResult` in that `rerender` and `unmount` are async functions. +The `RenderHookAsyncResult` differs from `RenderHookResult` in that `rerenderAsync` and `unmountAsync` are async functions. ```ts import { renderHookAsync, act } from '@testing-library/react-native'; test('should handle async hook behavior', async () => { - const { result, rerender } = await renderHookAsync(useAsyncHook); + const { result, rerenderAsync } = await renderHookAsync(useAsyncHook); // Test initial state expect(result.current.loading).toBe(true); @@ -172,7 +174,7 @@ test('should handle async hook behavior', async () => { }); // Re-render to get updated state - await rerender(); + await rerenderAsync(); expect(result.current.loading).toBe(false); }); ``` From 2106b0ccb5e975e91b85468e5e6328e761ff8891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Jastrze=CC=A8bski?= Date: Mon, 11 Aug 2025 14:51:36 +0200 Subject: [PATCH 3/9] tweaks --- website/docs/13.x/docs/api/events/fire-event.mdx | 10 +++++----- website/docs/13.x/docs/api/render.mdx | 8 ++++---- website/docs/13.x/docs/api/screen.mdx | 12 ++---------- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/website/docs/13.x/docs/api/events/fire-event.mdx b/website/docs/13.x/docs/api/events/fire-event.mdx index d5c4297c1..65af25fbb 100644 --- a/website/docs/13.x/docs/api/events/fire-event.mdx +++ b/website/docs/13.x/docs/api/events/fire-event.mdx @@ -170,7 +170,7 @@ fireEvent.scroll(screen.getByText('scroll-view'), eventData); Prefer using [`user.scrollTo`](docs/api/events/user-event#scrollto) over `fireEvent.scroll` for `ScrollView`, `FlatList`, and `SectionList` components. User Event provides a more realistic event simulation based on React Native runtime behavior. ::: -## `fireEventAsync` {#async} +## `fireEventAsync` {#fire-event-async} :::info RNTL minimal version @@ -186,7 +186,7 @@ async function fireEventAsync( ): Promise; ``` -The `fireEventAsync` function is the async version of `fireEvent` designed for working with React 19 and React Suspense. This function uses async `act` function internally to ensure all pending React updates are executed during event handling. +The `fireEventAsync` function is the async version of [`fireEvent`](#fire-event) designed for working with React 19 and React Suspense. This function uses async `act` function internally to ensure all pending React updates are executed during event handling. ```jsx import { renderAsync, screen, fireEventAsync } from '@testing-library/react-native'; @@ -214,7 +214,7 @@ fireEventAsync.press: ( ) => Promise ``` -Async version of `fireEvent.press` designed for React 19 and React Suspense. Use when `press` event handlers trigger suspense boundaries. +Async version of [`fireEvent.press`](#press) designed for React 19 and React Suspense. Use when `press` event handlers trigger suspense boundaries. ### `fireEventAsync.changeText` {#async-change-text} @@ -229,7 +229,7 @@ fireEventAsync.changeText: ( ) => Promise ``` -Async version of `fireEvent.changeText` designed for React 19 and React Suspense. Use when `changeText` event handlers trigger suspense boundaries. +Async version of [`fireEvent.changeText`](#change-text) designed for React 19 and React Suspense. Use when `changeText` event handlers trigger suspense boundaries. ### `fireEventAsync.scroll` {#async-scroll} @@ -244,4 +244,4 @@ fireEventAsync.scroll: ( ) => Promise ``` -Async version of `fireEvent.scroll` designed for React 19 and React Suspense. Use when `scroll` event handlers trigger suspense boundaries. +Async version of [`fireEvent.scroll`](#scroll) designed for React 19 and React Suspense. Use when `scroll` event handlers trigger suspense boundaries. diff --git a/website/docs/13.x/docs/api/render.mdx b/website/docs/13.x/docs/api/render.mdx index b61e70028..9ae4417a0 100644 --- a/website/docs/13.x/docs/api/render.mdx +++ b/website/docs/13.x/docs/api/render.mdx @@ -1,6 +1,6 @@ -# `render` function +# `render` API -## `render` +## `render` function {#render} ```jsx function render( @@ -67,7 +67,7 @@ The `render` function returns the same queries and utilities as the [`screen`](d See [this article](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#not-using-screen) from Kent C. Dodds for more details. -## `renderAsync` function +## `renderAsync` function {#render-async} :::info RNTL minimal version @@ -82,7 +82,7 @@ async function renderAsync( ): Promise; ``` -The `renderAsync` function is the async version of `render` designed for working with React 19 and React Suspense. This function uses async `act` function internally to ensure all pending React updates are executed during rendering. +The `renderAsync` function is the async version of [`render`](#render) designed for working with React 19 and React Suspense. This function uses async `act` function internally to ensure all pending React updates are executed during rendering. ```jsx import { renderAsync, screen } from '@testing-library/react-native'; diff --git a/website/docs/13.x/docs/api/screen.mdx b/website/docs/13.x/docs/api/screen.mdx index d4016d4f3..d9cf25865 100644 --- a/website/docs/13.x/docs/api/screen.mdx +++ b/website/docs/13.x/docs/api/screen.mdx @@ -46,16 +46,14 @@ Re-render the in-memory tree with a new root element. This simulates a React upd _Also available under `updateAsync` alias_ :::info RNTL minimal version - This API requires RNTL v13.3.0 or later. - ::: ```ts function rerenderAsync(element: React.Element): Promise; ``` -Async versions of `rerender` designed for working with React 19 and React Suspense. This method uses async `act` function internally to ensure all pending React updates are executed during updating. +Async versions of [`rerender`](#rerender) designed for working with React 19 and React Suspense. This method uses async `act` function internally to ensure all pending React updates are executed during updating. ```jsx import { renderAsync, screen } from '@testing-library/react-native'; @@ -63,9 +61,7 @@ import { renderAsync, screen } from '@testing-library/react-native'; test('async rerender test', async () => { await renderAsync(); - // Use async rerender when component has suspense or async behavior await screen.rerenderAsync(); - expect(screen.getByText('updated')).toBeOnTheScreen(); }); ``` @@ -87,21 +83,17 @@ Usually you should not need to call `unmount` as it is done automatically if you ### `unmountAsync` :::info RNTL minimal version - This API requires RNTL v13.3.0 or later. - ::: ```ts function unmountAsync(): Promise; ``` -Async version of `unmount` designed for working with React 19 and React Suspense. This method uses async `act` function internally to ensure all pending React updates are executed during unmounting. +Async version of [`unmount`](#unmount) designed for working with React 19 and React Suspense. This method uses async `act` function internally to ensure all pending React updates are executed during unmounting. :::note - Usually you should not need to call `unmountAsync` as it is done automatically if your test runner supports `afterEach` hook (like Jest, mocha, Jasmine). - ::: ### `debug` From 46e20444d11d3df2216bd84615abe99460248883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Jastrze=CC=A8bski?= Date: Mon, 11 Aug 2025 15:58:37 +0200 Subject: [PATCH 4/9] suspense docs --- website/docs/13.x/docs/guides/_meta.json | 2 +- website/docs/13.x/docs/guides/react-19.mdx | 56 ++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 website/docs/13.x/docs/guides/react-19.mdx diff --git a/website/docs/13.x/docs/guides/_meta.json b/website/docs/13.x/docs/guides/_meta.json index 5ae12d7e2..4b5f8b683 100644 --- a/website/docs/13.x/docs/guides/_meta.json +++ b/website/docs/13.x/docs/guides/_meta.json @@ -1 +1 @@ -["how-to-query", "troubleshooting", "faq", "community-resources"] +["how-to-query", "react-19", "troubleshooting", "faq", "community-resources"] diff --git a/website/docs/13.x/docs/guides/react-19.mdx b/website/docs/13.x/docs/guides/react-19.mdx new file mode 100644 index 000000000..47205e5a9 --- /dev/null +++ b/website/docs/13.x/docs/guides/react-19.mdx @@ -0,0 +1,56 @@ +# React 19 & Suspense Support + +React 19 introduced full support for React Suspense, `React.use()`, and other async rendering features to React Native. These new capabilities enable more sophisticated async patterns but also require updates to testing approaches. + +## Impact on React Rendering + +React 19's async rendering features make React's rendering process more asynchronous by nature. This requires the use of the `async act` helper when testing components that use these new APIs, which in turn affects several React Native Testing Library APIs. + +Note that `renderAsync`, and other changes support React 18. + +## New Async APIs in RNTL 13.3 + +To support React 19's async rendering, RNTL 13.3 introduces several new async APIs: + +- **[`renderAsync`](docs/api/render#render-async)** - async version of [`render`](docs/api/render) +- `screen` object + - **[`rerenderAsync`](docs/api/screen#rerender-async)** - async version of [`rerender`](docs/api/screen#rerender) + - **[`unmountAsync`](docs/api/screen#unmount-async)** - async version of [`unmount`](docs/api/screen#unmount) +- **[`fireEventAsync`](docs/api/fire-event#fire-event-async)** - async version of [`fireEvent`](docs/api/fire-event#fire-event) + +## Unchanged APIs + +Some APIs didn't require changes: + +- `screen` object: most of the methods, including queries +- **[`userEvent`](docs/api/user-event) didn't require API changes as it was already async +- Jest Matchers didn't require any changes as they work already processed output + +## Key Changes for Testing + +### Main Change: `renderAsync` + +The primary change is the introduction of [`renderAsync`](docs/api/render#renderasync), which requires making your tests `async` and using the `await` keyword: + +```tsx +// Before (React 18 and earlier) +test('my component', () => { + render(); + expect(screen.getByText('Hello')).toBeOnTheScreen(); +}); + +// After (React 19 with Suspense) +test('my component', async () => { + await renderAsync(); + expect(screen.getByText('Hello')).toBeOnTheScreen(); +}); +``` + +## Migration Strategy + +While these async APIs are new in RNTL 13.3, we expect them to become the default recommendation in the future. We advise: + +- **New testing code**: use the async APIs (`renderAsync`, etc.) for all new tests +- **Legacy testing code**: can continue using the synchronous versions (`render`, etc.) without any required changes + +This approach allows for gradual migration while ensuring compatibility with both React 18 and React 19 features. \ No newline at end of file From 0fe92e08b7ae5b15b585ca12008d3929759da405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Jastrze=CC=A8bski?= Date: Mon, 11 Aug 2025 16:04:11 +0200 Subject: [PATCH 5/9] . --- website/docs/13.x/docs/guides/react-19.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/13.x/docs/guides/react-19.mdx b/website/docs/13.x/docs/guides/react-19.mdx index 47205e5a9..2cb068a16 100644 --- a/website/docs/13.x/docs/guides/react-19.mdx +++ b/website/docs/13.x/docs/guides/react-19.mdx @@ -1,10 +1,10 @@ # React 19 & Suspense Support -React 19 introduced full support for React Suspense, `React.use()`, and other async rendering features to React Native. These new capabilities enable more sophisticated async patterns but also require updates to testing approaches. +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. ## Impact on React Rendering -React 19's async rendering features make React's rendering process more asynchronous by nature. This requires the use of the `async act` helper when testing components that use these new APIs, which in turn affects several React Native Testing Library APIs. +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. Note that `renderAsync`, and other changes support React 18. From f0c065c291acd21471095e5d8f4c4045bd975def Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Jastrze=CC=A8bski?= Date: Mon, 11 Aug 2025 16:04:15 +0200 Subject: [PATCH 6/9] . --- website/docs/13.x/docs/guides/react-19.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/13.x/docs/guides/react-19.mdx b/website/docs/13.x/docs/guides/react-19.mdx index 2cb068a16..def7d2d99 100644 --- a/website/docs/13.x/docs/guides/react-19.mdx +++ b/website/docs/13.x/docs/guides/react-19.mdx @@ -6,7 +6,7 @@ React 19 introduced full support for React Suspense, `React.use()`, and other as 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. -Note that `renderAsync`, and other changes support React 18. +Note that `renderAsync` and other async APIs also support React 18. ## New Async APIs in RNTL 13.3 @@ -23,8 +23,8 @@ To support React 19's async rendering, RNTL 13.3 introduces several new async AP Some APIs didn't require changes: - `screen` object: most of the methods, including queries -- **[`userEvent`](docs/api/user-event) didn't require API changes as it was already async -- Jest Matchers didn't require any changes as they work already processed output +- **[`userEvent`](docs/api/user-event)** didn't require API changes as it was already async +- **Jest Matchers** didn't require any changes as they work with already processed output ## Key Changes for Testing @@ -53,4 +53,4 @@ While these async APIs are new in RNTL 13.3, we expect them to become the defaul - **New testing code**: use the async APIs (`renderAsync`, etc.) for all new tests - **Legacy testing code**: can continue using the synchronous versions (`render`, etc.) without any required changes -This approach allows for gradual migration while ensuring compatibility with both React 18 and React 19 features. \ No newline at end of file +This approach allows for gradual migration while ensuring compatibility with both React 18 and React 19 features. From 28eb3580ebc1a18a3439acd0a61f6abc2a5a7551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Jastrze=CC=A8bski?= Date: Mon, 11 Aug 2025 16:10:22 +0200 Subject: [PATCH 7/9] . --- website/docs/13.x/docs/guides/react-19.mdx | 60 ++++++++++++++-------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/website/docs/13.x/docs/guides/react-19.mdx b/website/docs/13.x/docs/guides/react-19.mdx index def7d2d99..98bd6c55d 100644 --- a/website/docs/13.x/docs/guides/react-19.mdx +++ b/website/docs/13.x/docs/guides/react-19.mdx @@ -1,56 +1,72 @@ # React 19 & Suspense Support -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. +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. -## Impact on React Rendering +## Why New Testing APIs Are Needed -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. +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. -Note that `renderAsync` and other async APIs also support React 18. +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. ## New Async APIs in RNTL 13.3 -To support React 19's async rendering, RNTL 13.3 introduces several new async APIs: +RNTL 13.3 introduces async versions of the core testing APIs to handle React 19's async rendering: +**Rendering APIs:** - **[`renderAsync`](docs/api/render#render-async)** - async version of [`render`](docs/api/render) -- `screen` object - - **[`rerenderAsync`](docs/api/screen#rerender-async)** - async version of [`rerender`](docs/api/screen#rerender) - - **[`unmountAsync`](docs/api/screen#unmount-async)** - async version of [`unmount`](docs/api/screen#unmount) +- **[`screen.rerenderAsync`](docs/api/screen#rerender-async)** - async version of [`screen.rerender`](docs/api/screen#rerender) +- **[`screen.unmountAsync`](docs/api/screen#unmount-async)** - async version of [`screen.unmount`](docs/api/screen#unmount) + +**Event APIs:** - **[`fireEventAsync`](docs/api/fire-event#fire-event-async)** - async version of [`fireEvent`](docs/api/fire-event#fire-event) -## Unchanged APIs +## APIs That Remain Unchanged -Some APIs didn't require changes: +Many existing APIs continue to work without modification: -- `screen` object: most of the methods, including queries -- **[`userEvent`](docs/api/user-event)** didn't require API changes as it was already async -- **Jest Matchers** didn't require any changes as they work with already processed output +- **Query methods** - `screen.getBy*`, `screen.queryBy*`, `screen.findBy*` all work the same +- **[`userEvent`](docs/api/user-event)** - already async, so no API changes needed +- **Jest matchers** - work with already-rendered output, so no changes required -## Key Changes for Testing +## What Changes in Your Tests -### Main Change: `renderAsync` +### Making Tests Async -The primary change is the introduction of [`renderAsync`](docs/api/render#renderasync), which requires making your tests `async` and using the `await` keyword: +The main change is using [`renderAsync`](docs/api/render#renderasync) instead of `render`, which requires: +1. Making your test function `async` +2. Adding `await` before `renderAsync` ```tsx -// Before (React 18 and earlier) +// Synchronous approach (React 18 pattern) test('my component', () => { render(); expect(screen.getByText('Hello')).toBeOnTheScreen(); }); -// After (React 19 with Suspense) +// Async approach (React 19 ready) test('my component', async () => { await renderAsync(); expect(screen.getByText('Hello')).toBeOnTheScreen(); }); ``` +### When to Use Async APIs + +Use the async APIs when your components: +- Use React Suspense for data fetching or code splitting +- Call `React.use()` for reading promises or context +- Have async state updates that need proper `act()` handling + ## Migration Strategy -While these async APIs are new in RNTL 13.3, we expect them to become the default recommendation in the future. We advise: +### For New Projects +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. -- **New testing code**: use the async APIs (`renderAsync`, etc.) for all new tests -- **Legacy testing code**: can continue using the synchronous versions (`render`, etc.) without any required changes +### For Existing Projects +You can migrate gradually: +- **Existing tests** continue to work with synchronous APIs (`render`, etc.) +- **New tests** should use async APIs +- **Tests with Suspense/React.use()** must use async APIs -This approach allows for gradual migration while ensuring compatibility with both React 18 and React 19 features. +### Future Direction +We expect async APIs to become the default recommendation as React 19 adoption grows. Starting with async APIs now will save migration effort later. From 18a683d7981f474bdd0c6c445c5e42fef389cf06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Jastrze=CC=A8bski?= Date: Mon, 11 Aug 2025 16:16:22 +0200 Subject: [PATCH 8/9] . --- website/docs/13.x/docs/guides/react-19.mdx | 46 ++++++++++------------ 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/website/docs/13.x/docs/guides/react-19.mdx b/website/docs/13.x/docs/guides/react-19.mdx index 98bd6c55d..dc89a0248 100644 --- a/website/docs/13.x/docs/guides/react-19.mdx +++ b/website/docs/13.x/docs/guides/react-19.mdx @@ -1,36 +1,32 @@ # React 19 & Suspense Support -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. +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). -## Why New Testing APIs Are Needed +When testing components that use these features, React requires the [`async act`](https://react.dev/reference/react/act) helper to handle async state updates. This means React Native Testing Library needs new async versions of its core APIs. These async APIs work with both React 18 and React 19. -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. - -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. - -## New Async APIs in RNTL 13.3 +## New async APIs RNTL 13.3 introduces async versions of the core testing APIs to handle React 19's async rendering: **Rendering APIs:** -- **[`renderAsync`](docs/api/render#render-async)** - async version of [`render`](docs/api/render) -- **[`screen.rerenderAsync`](docs/api/screen#rerender-async)** - async version of [`screen.rerender`](docs/api/screen#rerender) -- **[`screen.unmountAsync`](docs/api/screen#unmount-async)** - async version of [`screen.unmount`](docs/api/screen#unmount) +- **[`renderAsync`](docs/api/render#render-async)** - async version of `render` +- **[`screen.rerenderAsync`](docs/api/screen#rerender-async)** - async version of `screen.rerender` +- **[`screen.unmountAsync`](docs/api/screen#unmount-async)** - async version of `screen.unmount` **Event APIs:** -- **[`fireEventAsync`](docs/api/fire-event#fire-event-async)** - async version of [`fireEvent`](docs/api/fire-event#fire-event) +- **[`fireEventAsync`](docs/api/fire-event#fire-event-async)** - async version of `fireEvent` -## APIs That Remain Unchanged +## APIs that remain unchanged Many existing APIs continue to work without modification: -- **Query methods** - `screen.getBy*`, `screen.queryBy*`, `screen.findBy*` all work the same -- **[`userEvent`](docs/api/user-event)** - already async, so no API changes needed -- **Jest matchers** - work with already-rendered output, so no changes required +- **[Query methods](docs/api/queries)**: `screen.getBy*`, `screen.queryBy*`, `screen.findBy*` - all work the same +- **[User Event API](docs/api/events/user-event)** - already async, so no API changes needed +- **[Jest matchers](docs/api/jest-matchers)** - work with already-rendered output, so no changes required -## What Changes in Your Tests +## What changes in your tests -### Making Tests Async +### Making tests async The main change is using [`renderAsync`](docs/api/render#renderasync) instead of `render`, which requires: 1. Making your test function `async` @@ -50,23 +46,23 @@ test('my component', async () => { }); ``` -### When to Use Async APIs +### When to use async APIs Use the async APIs when your components: - Use React Suspense for data fetching or code splitting - Call `React.use()` for reading promises or context - Have async state updates that need proper `act()` handling -## Migration Strategy +## Migration strategy -### For New Projects -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. +### New projects +Use the async-ready APIs (`renderAsync`, User Event, Jest Matchers, etc.) from the start. They work with both React 18 and React 19. -### For Existing Projects +### Existing projects You can migrate gradually: - **Existing tests** continue to work with synchronous APIs (`render`, etc.) - **New tests** should use async APIs -- **Tests with Suspense/React.use()** must use async APIs +- **Tests with Suspense/`React.use()`** must use async APIs -### Future Direction -We expect async APIs to become the default recommendation as React 19 adoption grows. Starting with async APIs now will save migration effort later. +### Future direction +Async APIs will become the default recommendation as React 19 adoption grows. Starting with them now saves migration effort later. From 751d72241135f9cf816569433a95ccc8b9f41f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Jastrze=CC=A8bski?= Date: Mon, 11 Aug 2025 16:25:56 +0200 Subject: [PATCH 9/9] . --- website/docs/13.x/docs/guides/react-19.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/13.x/docs/guides/react-19.mdx b/website/docs/13.x/docs/guides/react-19.mdx index dc89a0248..6a98a8609 100644 --- a/website/docs/13.x/docs/guides/react-19.mdx +++ b/website/docs/13.x/docs/guides/react-19.mdx @@ -14,7 +14,7 @@ RNTL 13.3 introduces async versions of the core testing APIs to handle React 19' - **[`screen.unmountAsync`](docs/api/screen#unmount-async)** - async version of `screen.unmount` **Event APIs:** -- **[`fireEventAsync`](docs/api/fire-event#fire-event-async)** - async version of `fireEvent` +- **[`fireEventAsync`](docs/api/events/fire-event#fire-event-async)** - async version of `fireEvent` ## APIs that remain unchanged