|
2 | 2 |
|
3 | 3 | ```ts |
4 | 4 | function renderHook<Result, Props>( |
5 | | - callback: (props?: Props) => Result, |
| 5 | + hookFn: (props?: Props) => Result, |
6 | 6 | options?: RenderHookOptions<Props> |
7 | 7 | ): RenderHookResult<Result, Props>; |
8 | 8 | ``` |
@@ -129,3 +129,52 @@ it('should use context value', () => { |
129 | 129 | // ... |
130 | 130 | }); |
131 | 131 | ``` |
| 132 | + |
| 133 | +## `renderHookAsync` function |
| 134 | + |
| 135 | +```ts |
| 136 | +async function renderHookAsync<Result, Props>( |
| 137 | + hookFn: (props?: Props) => Result, |
| 138 | + options?: RenderHookOptions<Props> |
| 139 | +): Promise<RenderHookAsyncResult<Result, Props>>; |
| 140 | +``` |
| 141 | + |
| 142 | +Async versions of `renderHook` 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 rendering. |
| 143 | + |
| 144 | +- **Returns a Promise**: Should be awaited |
| 145 | +- **Async methods**: Both `rerender` and `unmount` return Promises and should be awaited |
| 146 | +- **Suspense support**: Compatible with React Suspense boundaries and `React.use()` |
| 147 | + |
| 148 | +### Result {#result-async} |
| 149 | + |
| 150 | +```ts |
| 151 | +interface RenderHookAsyncResult<Result, Props> { |
| 152 | + result: { current: Result }; |
| 153 | + rerender: (props: Props) => Promise<void>; |
| 154 | + unmount: () => Promise<void>; |
| 155 | +} |
| 156 | +``` |
| 157 | + |
| 158 | +The `RenderHookAsyncResult` differs from `RenderHookResult` in that `rerender` and `unmount` are async functions. |
| 159 | + |
| 160 | +```ts |
| 161 | +import { renderHookAsync, act } from '@testing-library/react-native'; |
| 162 | + |
| 163 | +test('should handle async hook behavior', async () => { |
| 164 | + const { result, rerender } = await renderHookAsync(useAsyncHook); |
| 165 | + |
| 166 | + // Test initial state |
| 167 | + expect(result.current.loading).toBe(true); |
| 168 | + |
| 169 | + // Wait for async operation to complete |
| 170 | + await act(async () => { |
| 171 | + await new Promise((resolve) => setTimeout(resolve, 100)); |
| 172 | + }); |
| 173 | + |
| 174 | + // Re-render to get updated state |
| 175 | + await rerender(); |
| 176 | + expect(result.current.loading).toBe(false); |
| 177 | +}); |
| 178 | +``` |
| 179 | + |
| 180 | +Use `renderHookAsync` when testing hooks that use React Suspense, `React.use()`, or other concurrent features where timing of re-renders matters. |
0 commit comments