Skip to content

Instantly share code, notes, and snippets.

@freddi301
Created September 15, 2023 08:53
Show Gist options
  • Save freddi301/7fcf2c919ef8ddd43f48145e9aafb6f9 to your computer and use it in GitHub Desktop.
Save freddi301/7fcf2c919ef8ddd43f48145e9aafb6f9 to your computer and use it in GitHub Desktop.
React hook to measure an element before rendering it
/**
* React hook to measure an element before rendering it
* given some jsx it renders it in a hidden div then measures its size
* the hook returns width and height and portal
* @important the portal must be in the page to be able to render the hidden div for measurements
* @warning the jsx will be renred probably twice, once for measurement, and where you actually use it
*/
export function useDomSize(children: JSX.Element) {
const [width, setWidth] = React.useState(0);
const [height, setHeight] = React.useState(0);
const invisibleContainer = React.useMemo(() => {
const element = document.createElement("div");
element.style.position = "fixed";
element.style.top = "-10000px";
element.style.left = "-10000px";
return element;
}, []);
(window as any).prova = invisibleContainer;
const portal = ReactDOM.createPortal(children, invisibleContainer);
React.useLayoutEffect(() => {
document.body.appendChild(invisibleContainer);
return () => {
document.body.removeChild(invisibleContainer);
};
}, [invisibleContainer]);
React.useLayoutEffect(() => {
const { width, height } = invisibleContainer.getBoundingClientRect();
setWidth(width);
setHeight(height);
}, [children, invisibleContainer]);
return { portal, width, height };
}
function Example() {
const tooltip = (
<p>
Helloworld
<br />
</p>
);
const tooltipDimensions = useDomSize(tooltip);
return (
<React.Fragment>
{tooltip}
{tooltipDimensions.portal}
{tooltipDimensions.width} {tooltipDimensions.height}
</React.Fragment>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment