Skip to content

Instantly share code, notes, and snippets.

@takumifukasawa
Created November 4, 2020 13:48
Show Gist options
  • Save takumifukasawa/ae2e8ff436ad0947fc84e670d7e2bf24 to your computer and use it in GitHub Desktop.
Save takumifukasawa/ae2e8ff436ad0947fc84e670d7e2bf24 to your computer and use it in GitHub Desktop.
React: get dom dimensions custom hooks
import { RefObject, useEffect, useRef, useState } from "react";
type Dimensions = {
bottom: number;
height: number;
left: number;
right: number;
top: number;
width: number;
x: number;
y: number;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function parseDimensions(bounds: any): Dimensions {
return {
bottom: bounds.bottom,
height: bounds.height,
left: bounds.left,
right: bounds.right,
top: bounds.top,
width: bounds.width,
x: bounds.x,
y: bounds.y,
};
}
/**
* refs: https://github.com/Swizec/useDimensions
*
* @export
* @template T
* @returns {([
* RefObject<T>,
* Dimensions | null,
* () => void
* ])}
*/
export default function useDimensions<T extends HTMLElement>(): [
RefObject<T>,
Dimensions | null,
() => void
] {
const ref = useRef<T>(null);
const [dimensions, setDimensions] = useState<Dimensions | null>(null);
const handleResize = () => {
if (!ref.current) {
return;
}
const boundingRect = ref.current.getBoundingClientRect();
const res = parseDimensions(boundingRect.toJSON());
// for debug
// console.log("[useDimensions]", res);
setDimensions(res);
};
useEffect(() => {
if (!ref.current) {
return () => {};
}
handleResize(); // call once manually
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, [ref.current]);
return [ref, dimensions, handleResize];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment