diff --git a/src/__tests__/renderHook.js b/src/__tests__/renderHook.js
index fe7551a2..53ff6f1f 100644
--- a/src/__tests__/renderHook.js
+++ b/src/__tests__/renderHook.js
@@ -1,4 +1,6 @@
import React from 'react'
+import ReactDOM from 'react-dom'
+
import {renderHook} from '../pure'
const isReact18 = React.version.startsWith('18.')
@@ -111,3 +113,46 @@ testGateReact19('legacyRoot throws', () => {
`\`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.`,
)
})
+
+test('supports initialArgs for multi-parameter hooks', () => {
+ const useTestHook = (a, b, c) => a + b + c
+ const {result} = renderHook(useTestHook, {initialArgs: [1, 2, 3]})
+
+ expect(result.current).toBe(6)
+})
+
+test('rerender supports multiple parameters', () => {
+ const useTestHook = (a, b) => a * b
+ const {result, rerender} = renderHook(useTestHook, {initialArgs: [2, 3]})
+
+ expect(result.current).toBe(6)
+
+ rerender(4, 5)
+ expect(result.current).toBe(20)
+})
+
+test('throws error when both initialProps and initialArgs are used', () => {
+ const useTestHook = (a, b) => a + b
+
+ expect(() =>
+ renderHook(useTestHook, {initialProps: 1, initialArgs: [2, 3]}),
+ ).toThrow('Cannot use both initialProps and initialArgs. Choose one.')
+})
+
+test('throws an error when legacyRoot is used in unsupported React versions', () => {
+ const useTestHook = () => 'test'
+
+ const {render: originalRender} = ReactDOM
+
+ ReactDOM.render = undefined
+
+ expect(() => {
+ renderHook(useTestHook, {legacyRoot: true})
+ }).toThrowError(
+ '`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.',
+ )
+
+ ReactDOM.render = originalRender
+})
diff --git a/src/pure.js b/src/pure.js
index fe95024a..2975a6bc 100644
--- a/src/pure.js
+++ b/src/pure.js
@@ -290,7 +290,11 @@ function cleanup() {
}
function renderHook(renderCallback, options = {}) {
- const {initialProps, ...renderOptions} = options
+ const {initialProps, initialArgs, ...renderOptions} = options
+
+ if (initialProps !== undefined && initialArgs !== undefined) {
+ throw new Error('Cannot use both initialProps and initialArgs. Choose one.')
+ }
if (renderOptions.legacyRoot && typeof ReactDOM.render !== 'function') {
const error = new Error(
@@ -303,9 +307,18 @@ function renderHook(renderCallback, options = {}) {
}
const result = React.createRef()
+ const isUsingArgs = initialArgs !== undefined
function TestComponent({renderCallbackProps}) {
- const pendingResult = renderCallback(renderCallbackProps)
+ // Handle both cases: when renderCallbackProps is an array to spread,
+ // and when it's a single value not to spread
+ const pendingResult = isUsingArgs
+ ? renderCallback(
+ ...(Array.isArray(renderCallbackProps)
+ ? renderCallbackProps
+ : [renderCallbackProps]),
+ )
+ : renderCallback(renderCallbackProps)
React.useEffect(() => {
result.current = pendingResult
@@ -315,13 +328,17 @@ function renderHook(renderCallback, options = {}) {
}
const {rerender: baseRerender, unmount} = render(
- ,
+ ,
renderOptions,
)
- function rerender(rerenderCallbackProps) {
+ function rerender(...newArgs) {
return baseRerender(
- ,
+ ,
)
}
diff --git a/types/index.d.ts b/types/index.d.ts
index 2f814a6d..47f2a24c 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -249,6 +249,7 @@ export interface RenderHookOptions<
* to use the rerender utility to change the values passed to your hook.
*/
initialProps?: Props | undefined
+ initialArgs?: Props | undefined
}
/**
@@ -262,7 +263,7 @@ export function renderHook<
Container extends RendererableContainer | HydrateableContainer = HTMLElement,
BaseElement extends RendererableContainer | HydrateableContainer = Container,
>(
- render: (initialProps: Props) => Result,
+ render: (initialProps: Props, initialArgs: Props) => Result,
options?: RenderHookOptions | undefined,
): RenderHookResult