// source: https://github.com/testing-library/react-testing-library/blob/887d95b84ddbcedb46932bf52fbda4518abb35c8/src/pure.js#L118 import { act, render } from '@testing-library/react'; import React, { ComponentType, createRef, Fragment, MutableRefObject, StrictMode, useEffect, } from 'react'; interface RenderHookResult { rerender: (props: Props) => void; result: { current: Result }; unmount: () => void; } interface RenderHookOptions { initialProps: Props; wrapper?: ComponentType; strict?: boolean; } interface RenderHookResultWithoutProps { rerender: () => void; result: { current: Result }; unmount: () => void; } interface RenderHookOptionsWithoutProps { wrapper?: ComponentType; strict?: boolean; } export function renderHook( renderCallback: () => Result, options?: RenderHookOptionsWithoutProps, ): RenderHookResultWithoutProps; export function renderHook( renderCallback: (props: Props) => Result, options: RenderHookOptions, ): RenderHookResult; export function renderHook( renderCallback: (props?: Props) => Result, options: Partial> = {}, ): RenderHookResult | RenderHookResultWithoutProps { const { initialProps, wrapper, strict = true } = options; const Wrapper = strict ? StrictMode : Fragment; const result: MutableRefObject = createRef() as MutableRefObject; function TestComponent({ renderCallbackProps, }: { renderCallbackProps?: Props; }) { const pendingResult = renderCallback(renderCallbackProps); useEffect(() => { result.current = pendingResult; }); return null; } const { rerender: baseRerender, unmount } = render( , { wrapper }, ); function rerender(rerenderCallbackProps?: Props) { return baseRerender( , ); } return { result, rerender, unmount }; } export { act };