# All files / src useEnsuredRef.ts

100% Statements 56/56
100% Branches 2/2
100% Functions 1/1
100% Lines 56/56

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
    571x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    5670x
    5670x
    5670x
    5670x
    5670x
    1324x
    1324x
    1324x
    5670x
    5670x
    5670x
    5670x
    5670x
     "use client";
    import type { MutableRefObject, Ref, RefCallback } from "react";
    import { useCallback, useRef } from "react";
    import { applyRef } from "./utils/applyRef.js";

    /**
     * @remarks \@since 2.3.0
     * @internal
     */
    export type EnsuredRefs<E extends HTMLElement> = readonly [
      MutableRefObject<E | null>,
      RefCallback<E | null>,
    ];

    /**
     * This is mostly an internal hook that allows for an optional ref (normally
     * from props or hook options) to be merged with a hook's required `ref`. This
     * will return a MutableRefObject used for DOM manipulation in a custom hook
     * followed by a ref callback function that should be passed to the DOM node
     * that will ensure that both the optional `propRef` and hook ref are updated.
     *
     * @example
     * Simple Example
     * ```tsx
     * import { HTMLAttributes, forwardRef } from "react";
     * import { useEnsuredRef } from "@react-md/core";
     *
     * export type ExampleProps = HTMLAttributes<HTMLDivElement>;
     *
     * export const Example = forwardRef<HTMLDivElement, ExampleProps>(function Example(props, ref) {
     *   const [nodeRef, refHandler] = useEnsuredRef(ref);
     *   useEffect(() => {
     *     // do something with nodeRef.current
     *   }, [nodeRef])
     *
     *   return <div ref={refHandler} />;
     * });
     * ```
     *
     * @remarks \@since 2.3.0
     * @internal
     */
    export function useEnsuredRef<E extends HTMLElement>(
      propRef?: Ref<E | null>
    ): EnsuredRefs<E> {
      const ref = useRef<E | null>(null);
      const refHandler = useCallback(
        (instance: E | null) => {
          applyRef(instance, propRef);
          ref.current = instance;
        },
        [propRef]
      );

      return [ref, refHandler];
    }