Skip to content

Commit 69c631d

Browse files
Add reactStrictMode as an option to render
1 parent 65bc994 commit 69c631d

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

src/__tests__/render.js

+34
Original file line numberDiff line numberDiff line change
@@ -262,4 +262,38 @@ describe('render API', () => {
262262
`\`legacyRoot: true\` is not supported in this version of React. If your app runs React 19 or later, you should remove this flag. If your app runs React 18 or earlier, visit https://react.dev/blog/2022/03/08/react-18-upgrade-guide for upgrade instructions.`,
263263
)
264264
})
265+
266+
test('reactStrictMode in renderOptions has precedence over config when rendering', () => {
267+
const wrapperComponentMountEffect = jest.fn()
268+
function WrapperComponent({children}) {
269+
React.useEffect(() => {
270+
wrapperComponentMountEffect()
271+
})
272+
273+
return children
274+
}
275+
const ui = <div />
276+
configure({reactStrictMode: false})
277+
278+
render(ui, {wrapper: WrapperComponent, reactStrictMode: true})
279+
280+
expect(wrapperComponentMountEffect).toHaveBeenCalledTimes(2);
281+
})
282+
283+
test('reactStrictMode in config is used when renderOptions does not specify reactStrictMode', () => {
284+
const wrapperComponentMountEffect = jest.fn()
285+
function WrapperComponent({children}) {
286+
React.useEffect(() => {
287+
wrapperComponentMountEffect()
288+
})
289+
290+
return children
291+
}
292+
const ui = <div />
293+
configure({reactStrictMode: true})
294+
295+
render(ui, {wrapper: WrapperComponent})
296+
297+
expect(wrapperComponentMountEffect).toHaveBeenCalledTimes(2);
298+
})
265299
})

src/pure.js

+11-7
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ const mountedContainers = new Set()
7777
*/
7878
const mountedRootEntries = []
7979

80-
function strictModeIfNeeded(innerElement) {
81-
return getConfig().reactStrictMode
80+
function strictModeIfNeeded(innerElement, reactStrictMode) {
81+
return reactStrictMode ?? getConfig().reactStrictMode
8282
? React.createElement(React.StrictMode, null, innerElement)
8383
: innerElement
8484
}
@@ -91,14 +91,14 @@ function wrapUiIfNeeded(innerElement, wrapperComponent) {
9191

9292
function createConcurrentRoot(
9393
container,
94-
{hydrate, onCaughtError, onRecoverableError, ui, wrapper: WrapperComponent},
94+
{hydrate, onCaughtError, onRecoverableError, ui, wrapper: WrapperComponent, reactStrictMode},
9595
) {
9696
let root
9797
if (hydrate) {
9898
act(() => {
9999
root = ReactDOMClient.hydrateRoot(
100100
container,
101-
strictModeIfNeeded(wrapUiIfNeeded(ui, WrapperComponent)),
101+
strictModeIfNeeded(wrapUiIfNeeded(ui, WrapperComponent), reactStrictMode),
102102
{onCaughtError, onRecoverableError},
103103
)
104104
})
@@ -144,17 +144,17 @@ function createLegacyRoot(container) {
144144

145145
function renderRoot(
146146
ui,
147-
{baseElement, container, hydrate, queries, root, wrapper: WrapperComponent},
147+
{baseElement, container, hydrate, queries, root, wrapper: WrapperComponent, reactStrictMode},
148148
) {
149149
act(() => {
150150
if (hydrate) {
151151
root.hydrate(
152-
strictModeIfNeeded(wrapUiIfNeeded(ui, WrapperComponent)),
152+
strictModeIfNeeded(wrapUiIfNeeded(ui, WrapperComponent), reactStrictMode),
153153
container,
154154
)
155155
} else {
156156
root.render(
157-
strictModeIfNeeded(wrapUiIfNeeded(ui, WrapperComponent)),
157+
strictModeIfNeeded(wrapUiIfNeeded(ui, WrapperComponent), reactStrictMode),
158158
container,
159159
)
160160
}
@@ -180,6 +180,7 @@ function renderRoot(
180180
baseElement,
181181
root,
182182
wrapper: WrapperComponent,
183+
reactStrictMode,
183184
})
184185
// Intentionally do not return anything to avoid unnecessarily complicating the API.
185186
// folks can use all the same utilities we return in the first place that are bound to the container
@@ -212,6 +213,7 @@ function render(
212213
queries,
213214
hydrate = false,
214215
wrapper,
216+
reactStrictMode,
215217
} = {},
216218
) {
217219
if (onUncaughtError !== undefined) {
@@ -248,6 +250,7 @@ function render(
248250
onRecoverableError,
249251
ui,
250252
wrapper,
253+
reactStrictMode,
251254
})
252255

253256
mountedRootEntries.push({container, root})
@@ -273,6 +276,7 @@ function render(
273276
hydrate,
274277
wrapper,
275278
root,
279+
reactStrictMode,
276280
})
277281
}
278282

types/index.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ export interface RenderOptions<
156156
* @see https://testing-library.com/docs/react-testing-library/api/#wrapper
157157
*/
158158
wrapper?: React.JSXElementConstructor<{children: React.ReactNode}> | undefined
159+
/**
160+
* When enabled, <StrictMode> is rendered around the inner element.
161+
* If defined, overrides the value of `reactStrictMode` set in `configure`.
162+
*/
163+
reactStrictMode?: boolean
159164
}
160165

161166
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>

0 commit comments

Comments
 (0)