From ac466f06efee9daee9070a9f4b02561697016888 Mon Sep 17 00:00:00 2001 From: beefchimi Date: Sat, 13 Apr 2024 14:37:32 -0400 Subject: [PATCH] :sparkles: [useElementRect] Improve re-renders by destructuring rect --- src/hooks/useElementRect.ts | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/hooks/useElementRect.ts b/src/hooks/useElementRect.ts index 605acc7..b6976be 100644 --- a/src/hooks/useElementRect.ts +++ b/src/hooks/useElementRect.ts @@ -22,17 +22,32 @@ const INITIAL_RECT: RectSubset = { height: 0, }; +function extractRectSubset( + {top, right, bottom, left, width, height}: DOMRect, + round = false, +) { + return { + top: round ? Math.round(top) : top, + right: round ? Math.round(right) : right, + bottom: round ? Math.round(bottom) : bottom, + left: round ? Math.round(left) : left, + width: round ? Math.round(width) : width, + height: round ? Math.round(height) : height, + }; +} + // TODO: Do we want to create and provide the `ref`, // or accept it as an option? -export function useElementRect() { +export function useElementRect(round = false) { const ref = useRef(null); const [rect, setRect] = useState(INITIAL_RECT); const updateRect = useCallback(() => { - if (ref.current) { - setRect(ref.current.getBoundingClientRect()); - } - }, []); + if (!ref.current) return; + + const domRect = ref.current.getBoundingClientRect(); + setRect(extractRectSubset(domRect, round)); + }, [round]); const {scrollX, scrollY, visibleWidth, visibleHeight} = useWindowScroll({ updateStrategy: 'aggressive', @@ -42,11 +57,12 @@ export function useElementRect() { useIsoEffect(() => { updateRect(); - }, [scrollX, scrollY, visibleWidth, visibleHeight]); + }, [updateRect, scrollX, scrollY, visibleWidth, visibleHeight]); return { ref, - rect, updateRect, + // Destructuring the `rect` as an alternative to memoizing the object. + ...rect, }; }