Skip to content

Instantly share code, notes, and snippets.

@saltnpixels
Created April 2, 2024 15:33
Show Gist options
  • Save saltnpixels/ea623716607e818653ab8d55990cdf46 to your computer and use it in GitHub Desktop.
Save saltnpixels/ea623716607e818653ab8d55990cdf46 to your computer and use it in GitHub Desktop.
React Resize Observer
import { useState, useLayoutEffect } from 'react';
import throttle from 'lodash.throttle';
function useResizeObserver(ref: React.MutableRefObject<any>) {
const [dimensions, setDimensions] = useState({
width: 0,
height: 0,
dimensionsLoaded: false,
});
useLayoutEffect(() => {
if (!ref.current) return;
// Define the throttled function outside of the observer callback
const throttledSetDimensions = throttle(({ width, height }) => {
setDimensions({
width,
height,
dimensionsLoaded: true,
});
}, 200); // Adjust the throttle time as needed
const observer = new ResizeObserver((entries) => {
for (const entry of entries) {
const { width, height } = entry.contentRect;
// Use the throttled function to update dimensions
throttledSetDimensions({ width, height });
}
});
observer.observe(ref.current);
// Initial dimensions check
const rect = ref.current.getBoundingClientRect();
throttledSetDimensions({ width: rect.width, height: rect.height });
return () => {
observer.disconnect();
// Cancel any pending updates when the component unmounts or the observed element changes
throttledSetDimensions.cancel();
};
}, [ref, ref.current]); // Dependency on the ref itself
return dimensions;
}
export { useResizeObserver };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment