0
# Component Rendering
1
2
Core functionality for rendering React components in test environments with full control over rendering options, container management, and lifecycle methods.
3
4
## Capabilities
5
6
### Render Function
7
8
Renders React components into a DOM container for testing, providing a complete testing interface with queries and utilities.
9
10
```typescript { .api }
11
/**
12
* Render a React component into a DOM container for testing
13
* @param ui - React component or element to render
14
* @param options - Rendering configuration options
15
* @returns RenderResult with queries and utilities
16
*/
17
// Two overloads for render function
18
function render<
19
Q extends Queries = typeof queries,
20
Container extends RendererableContainer | HydrateableContainer = HTMLElement,
21
BaseElement extends RendererableContainer | HydrateableContainer = Container,
22
>(
23
ui: React.ReactNode,
24
options: RenderOptions<Q, Container, BaseElement>,
25
): RenderResult<Q, Container, BaseElement>;
26
function render(
27
ui: React.ReactNode,
28
options?: Omit<RenderOptions, 'queries'> | undefined,
29
): RenderResult;
30
31
interface RenderOptions<
32
Q extends Queries = typeof queries,
33
Container extends RendererableContainer | HydrateableContainer = HTMLElement,
34
BaseElement extends RendererableContainer | HydrateableContainer = Container,
35
> {
36
/** Custom DOM container to render into */
37
container?: Container | undefined;
38
/** Base element for queries (defaults to document.body) */
39
baseElement?: BaseElement | undefined;
40
/** Use ReactDOM.hydrate instead of render for SSR testing */
41
hydrate?: boolean | undefined;
42
/** Force React 17 rendering mode instead of concurrent rendering */
43
legacyRoot?: boolean | undefined;
44
/** React 19+ error boundary callback */
45
onCaughtError?: ReactDOMClient.RootOptions extends {
46
onCaughtError: infer OnCaughtError
47
}
48
? OnCaughtError
49
: never;
50
/** React 18+ recoverable error callback */
51
onRecoverableError?: ReactDOMClient.RootOptions['onRecoverableError'];
52
/** Not supported - will throw error if provided */
53
onUncaughtError?: never;
54
/** Custom query functions to bind */
55
queries?: Q | undefined;
56
/** Wrapper component to render around the UI */
57
wrapper?: React.JSXElementConstructor<{children: React.ReactNode}> | undefined;
58
/** Enable React StrictMode for this render */
59
reactStrictMode?: boolean;
60
}
61
62
interface RenderResult<
63
Q extends Queries = typeof queries,
64
Container extends RendererableContainer | HydrateableContainer = HTMLElement,
65
BaseElement extends RendererableContainer | HydrateableContainer = Container,
66
> {
67
/** DOM container where component was rendered */
68
container: Container;
69
/** Base element used for queries */
70
baseElement: BaseElement;
71
/** Debug utility for logging DOM structure */
72
debug: (
73
baseElement?:
74
| RendererableContainer
75
| HydrateableContainer
76
| Array<RendererableContainer | HydrateableContainer>
77
| undefined,
78
maxLength?: number | undefined,
79
options?: prettyFormat.OptionsReceived | undefined,
80
) => void;
81
/** Re-render component with new props */
82
rerender: (ui: React.ReactNode) => void;
83
/** Unmount the component */
84
unmount: () => void;
85
/** Get DocumentFragment snapshot of container */
86
asFragment: () => DocumentFragment;
87
} & {[P in keyof Q]: BoundFunction<Q[P]>};
88
89
// Container types (React 18/19 compatible)
90
type RendererableContainer = ReactDOMClient.Container;
91
type HydrateableContainer = Parameters<typeof ReactDOMClient['hydrateRoot']>[0];
92
```
93
94
**Basic Usage:**
95
96
```typescript
97
import { render } from "@testing-library/react";
98
99
function MyComponent({ name }: { name: string }) {
100
return <h1>Hello {name}</h1>;
101
}
102
103
// Simple render
104
const { getByText } = render(<MyComponent name="World" />);
105
expect(getByText("Hello World")).toBeInTheDocument();
106
107
// Render with options
108
const { container, rerender } = render(<MyComponent name="Alice" />, {
109
wrapper: ({ children }) => <div className="test-wrapper">{children}</div>
110
});
111
112
// Re-render with different props
113
rerender(<MyComponent name="Bob" />);
114
```
115
116
### RenderResult Methods
117
118
The object returned by `render()` provides several utility methods for interacting with the rendered component.
119
120
#### Debug Method
121
122
Logs a pretty-printed representation of the DOM for debugging purposes.
123
124
```typescript { .api }
125
/**
126
* Log DOM structure for debugging
127
* @param element - Element(s) to debug (defaults to baseElement)
128
* @param maxLength - Maximum length of output
129
*/
130
debug(element?: Element | Element[], maxLength?: number): void;
131
```
132
133
**Usage Examples:**
134
135
```typescript
136
const { debug, getByTestId } = render(<MyComponent />);
137
138
// Debug entire rendered tree
139
debug();
140
141
// Debug specific element
142
const button = getByTestId("submit-button");
143
debug(button);
144
145
// Debug multiple elements
146
debug([button, getByTestId("cancel-button")]);
147
```
148
149
#### Rerender Method
150
151
Re-renders the component with new props while maintaining the same container.
152
153
```typescript { .api }
154
/**
155
* Re-render the component with new props
156
* @param ui - New React element to render
157
*/
158
rerender(ui: React.ReactNode): void;
159
```
160
161
**Usage Examples:**
162
163
```typescript
164
function Counter({ count }: { count: number }) {
165
return <div>Count: {count}</div>;
166
}
167
168
const { rerender, getByText } = render(<Counter count={0} />);
169
expect(getByText("Count: 0")).toBeInTheDocument();
170
171
// Update props
172
rerender(<Counter count={5} />);
173
expect(getByText("Count: 5")).toBeInTheDocument();
174
```
175
176
#### Unmount Method
177
178
Unmounts the component and removes it from the DOM.
179
180
```typescript { .api }
181
/**
182
* Unmount the component and clean up
183
*/
184
unmount(): void;
185
```
186
187
**Usage Examples:**
188
189
```typescript
190
const { unmount, container } = render(<MyComponent />);
191
192
// Component is rendered
193
expect(container.firstChild).toBeTruthy();
194
195
// Unmount component
196
unmount();
197
198
// Component is removed
199
expect(container.firstChild).toBeFalsy();
200
```
201
202
#### AsFragment Method
203
204
Returns a DocumentFragment containing a snapshot of the container's content.
205
206
```typescript { .api }
207
/**
208
* Get a DocumentFragment snapshot of the container
209
* @returns DocumentFragment with current container content
210
*/
211
asFragment(): DocumentFragment;
212
```
213
214
**Usage Examples:**
215
216
```typescript
217
const { asFragment, rerender } = render(<MyComponent version={1} />);
218
219
// Capture initial state
220
const firstSnapshot = asFragment();
221
222
// Update component
223
rerender(<MyComponent version={2} />);
224
225
// Compare snapshots
226
expect(asFragment()).not.toEqual(firstSnapshot);
227
```
228
229
### Advanced Rendering Options
230
231
#### Custom Containers
232
233
Provide specific DOM containers for components that require particular parent elements.
234
235
```typescript
236
// Render table row in proper context
237
const tableContainer = document.createElement('table');
238
const tbody = document.createElement('tbody');
239
tableContainer.appendChild(tbody);
240
241
render(
242
<tr>
243
<td>Cell content</td>
244
</tr>,
245
{ container: tbody }
246
);
247
```
248
249
#### Wrapper Components
250
251
Wrap components in providers or other context components.
252
253
```typescript
254
import { ThemeProvider } from "styled-components";
255
256
const { getByText } = render(<MyThemedComponent />, {
257
wrapper: ({ children }) => (
258
<ThemeProvider theme={{ primaryColor: "blue" }}>
259
{children}
260
</ThemeProvider>
261
)
262
});
263
```
264
265
#### Hydration Testing
266
267
Test server-side rendered components with hydration.
268
269
```typescript
270
// Pre-render HTML string
271
const container = document.createElement('div');
272
container.innerHTML = '<div>Server rendered content</div>';
273
274
// Hydrate with React component
275
render(<MyComponent />, {
276
container,
277
hydrate: true
278
});
279
```
280
281
#### React StrictMode
282
283
Enable React StrictMode for additional development warnings.
284
285
```typescript
286
render(<MyComponent />, {
287
reactStrictMode: true
288
});
289
```
290
291
### Error Handling
292
293
React 18+ error boundary integration for testing error scenarios.
294
295
```typescript
296
const errorHandler = jest.fn();
297
298
render(<ComponentThatMightError />, {
299
onCaughtError: errorHandler,
300
onRecoverableError: (error, errorInfo) => {
301
console.warn('Recoverable error:', error.message);
302
}
303
});
304
305
// Test error handling
306
fireEvent.click(getByText("Trigger Error"));
307
expect(errorHandler).toHaveBeenCalled();
308
```