Skip to content

Instantly share code, notes, and snippets.

@stoutlabs
Created September 11, 2021 09:17
Show Gist options
  • Save stoutlabs/e120738f296733821c1e0cdf24165415 to your computer and use it in GitHub Desktop.
Save stoutlabs/e120738f296733821c1e0cdf24165415 to your computer and use it in GitHub Desktop.
React Hook: useClientRect (Works with SSR/SSG and React v17.0.2)
import { useState, useCallback } from "react";
import useLayoutEffect from "hooks/useIsomorphicLayoutEffect";
function getDimensionObject(node) {
if (node.getBoundingClientRect) {
const rect = node.getBoundingClientRect();
return {
width: rect.width,
height: rect.height,
top: "y" in rect ? rect.y : rect.top,
left: "x" in rect ? rect.x : rect.left,
x: "x" in rect ? rect.x : rect.left,
y: "y" in rect ? rect.y : rect.top,
right: rect.right,
bottom: rect.bottom,
};
}
}
const useClientRect = () => {
const [node, setNode] = useState(null);
const [rect, setRect] = useState({});
const ref = useCallback(n => {
setNode(n);
}, []);
useLayoutEffect(() => {
const set = () =>
window.requestAnimationFrame(() =>
setRect(node ? getDimensionObject(node) : {})
);
if (node) {
set();
window.addEventListener("resize", set);
return () => {
setNode(null);
return window.removeEventListener("resize", set);
};
}
}, [node]);
return [ref, rect, node];
};
export default useClientRect;
import { useLayoutEffect, useEffect } from "react";
const useIsomorphicLayoutEffect =
typeof window !== "undefined" ? useLayoutEffect : useEffect;
export default useIsomorphicLayoutEffect;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment