react custom hook that returns the bounds of the element ref passed to it in typescript

You can create a custom hook in React to get the bounds of an element that is passed as a ref to your component as shown below:

import { useState, useEffect, RefObject } from 'react';

type Bounds = {
  top: number;
  left: number;
  width: number;
  height: number;
};

type UseBoundsProps = {
  ref: RefObject<HTMLElement>;
};

const useBounds = ({ ref }: UseBoundsProps): Bounds | null => {
  const [bounds, setBounds] = useState<Bounds | null>(null);

  useEffect(() => {
    const getElementBounds = () => {
      if (ref.current) {
        const { top, left, width, height } = ref.current.getBoundingClientRect();
        setBounds({ top, left, width, height });
      }
    }

    getElementBounds();

    window.addEventListener('resize', getElementBounds);

    return () => {
      window.removeEventListener('resize', getElementBounds);
    };
  }, [ref]);

  return bounds;
};

export default useBounds;
788 chars
38 lines

First, we define the Bounds type which represents the dimensions and position of the element. We also define a UseBoundsProps type which takes a ref property that is a RefObject to the element that we want to get its bounds.

Then, we define the useBounds function which takes the ref as a parameter and returns the Bounds object or null if the element hasn't been mounted yet.

Inside the useEffect hook, we define a getElementBounds function that gets the initial bounds of the element and updates the bounds state. We also register a window resize event listener to keep the bounds state updated if the window is resized. We also clean up the event listener when the ref is unmounted.

Finally, we return the bounds object from the hook.

To use this hook in a component, simply pass the ref of the element you want to get its bounds to the useBounds hook as shown below:

import useBounds from '<path-to>/useBounds';

const MyComponent = () => {
  const ref = useRef<HTMLDivElement>(null);

  const bounds = useBounds({ ref });

  return (
    <div ref={ref}>
      ...
    </div>
  );
}
216 chars
14 lines

In the above example, we create a ref with a useRef hook and pass it to the useBounds hook via an object with a ref property. We then attach the ref to the div element that we want to get its bounds. The bounds object can now be used in the component's render function.

gistlibby LogSnag