Skip to content

Commit e155799

Browse files
committed
feat: add render hook support for multiple arguments
1 parent c3e3d90 commit e155799

File tree

3 files changed

+49
-6
lines changed

3 files changed

+49
-6
lines changed

src/__tests__/renderHook.js

+25
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,28 @@ testGateReact19('legacyRoot throws', () => {
111111
`\`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.`,
112112
)
113113
})
114+
115+
test('supports initialArgs for multi-parameter hooks', () => {
116+
const useTestHook = (a, b, c) => a + b + c
117+
const {result} = renderHook(useTestHook, {initialArgs: [1, 2, 3]})
118+
119+
expect(result.current).toBe(6)
120+
})
121+
122+
test('rerender supports multiple parameters', () => {
123+
const useTestHook = (a, b) => a * b
124+
const {result, rerender} = renderHook(useTestHook, {initialArgs: [2, 3]})
125+
126+
expect(result.current).toBe(6)
127+
128+
rerender(4, 5)
129+
expect(result.current).toBe(20)
130+
})
131+
132+
test('throws error when both initialProps and initialArgs are used', () => {
133+
const useTestHook = (a, b) => a + b
134+
135+
expect(() =>
136+
renderHook(useTestHook, {initialProps: 1, initialArgs: [2, 3]}),
137+
).toThrow('Cannot use both initialProps and initialArgs. Choose one.')
138+
})

src/pure.js

+22-5
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,11 @@ function cleanup() {
290290
}
291291

292292
function renderHook(renderCallback, options = {}) {
293-
const {initialProps, ...renderOptions} = options
293+
const {initialProps, initialArgs, ...renderOptions} = options
294+
295+
if (initialProps !== undefined && initialArgs !== undefined) {
296+
throw new Error('Cannot use both initialProps and initialArgs. Choose one.')
297+
}
294298

295299
if (renderOptions.legacyRoot && typeof ReactDOM.render !== 'function') {
296300
const error = new Error(
@@ -303,9 +307,18 @@ function renderHook(renderCallback, options = {}) {
303307
}
304308

305309
const result = React.createRef()
310+
const isUsingArgs = initialArgs !== undefined
306311

307312
function TestComponent({renderCallbackProps}) {
308-
const pendingResult = renderCallback(renderCallbackProps)
313+
// Handle both cases: when renderCallbackProps is an array to spread,
314+
// and when it's a single value not to spread
315+
const pendingResult = isUsingArgs
316+
? renderCallback(
317+
...(Array.isArray(renderCallbackProps)
318+
? renderCallbackProps
319+
: [renderCallbackProps]),
320+
)
321+
: renderCallback(renderCallbackProps)
309322

310323
React.useEffect(() => {
311324
result.current = pendingResult
@@ -315,13 +328,17 @@ function renderHook(renderCallback, options = {}) {
315328
}
316329

317330
const {rerender: baseRerender, unmount} = render(
318-
<TestComponent renderCallbackProps={initialProps} />,
331+
<TestComponent
332+
renderCallbackProps={isUsingArgs ? initialArgs : initialProps}
333+
/>,
319334
renderOptions,
320335
)
321336

322-
function rerender(rerenderCallbackProps) {
337+
function rerender(...newArgs) {
323338
return baseRerender(
324-
<TestComponent renderCallbackProps={rerenderCallbackProps} />,
339+
<TestComponent
340+
renderCallbackProps={isUsingArgs ? newArgs : newArgs[0]}
341+
/>,
325342
)
326343
}
327344

types/index.d.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ export interface RenderHookOptions<
249249
* to use the rerender utility to change the values passed to your hook.
250250
*/
251251
initialProps?: Props | undefined
252+
initialArgs?: Props | undefined
252253
}
253254

254255
/**
@@ -262,7 +263,7 @@ export function renderHook<
262263
Container extends RendererableContainer | HydrateableContainer = HTMLElement,
263264
BaseElement extends RendererableContainer | HydrateableContainer = Container,
264265
>(
265-
render: (initialProps: Props) => Result,
266+
render: (initialProps: Props, initialArgs: Props) => Result,
266267
options?: RenderHookOptions<Props, Q, Container, BaseElement> | undefined,
267268
): RenderHookResult<Result, Props>
268269

0 commit comments

Comments
 (0)