# All files / src renderHook.tsx

100% Statements 10/10
100% Branches 0/0
100% Functions 4/4
100% Lines 10/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60

    3x
    3x

    3x

    5x

    5x
    5x

    5x

    3x

    1x

    3x

     import React from 'react';
    import type { ComponentType } from 'react';
    import render from './render';

    export type RenderHookResult<Result, Props> = {
      rerender: (props: Props) => void;
      result: { current: Result };
      unmount: () => void;
    };

    export type RenderHookOptions<Props> = Props extends
      | object
      | string
      | number
      | boolean
      ? {
          initialProps: Props;
          wrapper?: ComponentType<any>;
        }
      : { wrapper?: ComponentType<any>; initialProps?: never } | undefined;

    export function renderHook<Result, Props>(
      renderCallback: (props: Props) => Result,
      options?: RenderHookOptions<Props>
    ): RenderHookResult<Result, Props> {
      const initialProps = options?.initialProps;
      const wrapper = options?.wrapper;

      const result: React.MutableRefObject<Result | null> = React.createRef();

      function TestComponent({
        renderCallbackProps,
      }: {
        renderCallbackProps: Props;
      }) {
        const renderResult = renderCallback(renderCallbackProps);

        React.useEffect(() => {
          result.current = renderResult;
        });

        return null;
      }

      const { rerender: baseRerender, unmount } = render(
        // @ts-expect-error since option can be undefined, initialProps can be undefined when it should'nt
        <TestComponent renderCallbackProps={initialProps} />,
        { wrapper }
      );

      function rerender(rerenderCallbackProps: Props) {
        return baseRerender(
          <TestComponent renderCallbackProps={rerenderCallbackProps} />
        );
      }

      // @ts-expect-error result is ill typed because ref is initialized to null
      return { result, rerender, unmount };
    }