diff --git a/src/hooks/useResizeObserver/useResizeObserver.stories.tsx b/src/hooks/useResizeObserver/useResizeObserver.stories.tsx index ab258cc..56cd839 100644 --- a/src/hooks/useResizeObserver/useResizeObserver.stories.tsx +++ b/src/hooks/useResizeObserver/useResizeObserver.stories.tsx @@ -1,5 +1,7 @@ +/* eslint-disable react/jsx-no-literals, react-hooks/rules-of-hooks */ import type { Meta, StoryObj } from '@storybook/react'; -import { type ReactElement, useRef, useState } from 'react'; +import { useCallback, useRef, useState } from 'react'; +import { useToggle } from '../useToggle/useToggle.js'; import { useResizeObserver } from './useResizeObserver.js'; const meta = { @@ -10,30 +12,48 @@ export default meta; type Story = StoryObj; -function DemoComponent(): ReactElement { - const elementRef = useRef(null); - const [element, setElement] = useState(null); - - useResizeObserver(elementRef, () => { - // eslint-disable-next-line no-console - console.log('Element from RefObject resized'); - }); - - useResizeObserver(element, () => { - // eslint-disable-next-line no-console - console.log('Element from state resized'); - }); - - return ( - <> -
-
- - ); -} - export const Demo: Story = { render() { - return ; + const [enabled, onClick] = useToggle(true); + + const elementRef = useRef(null); + const [elementRefWidth, setElementRefWidth] = useState(Number.NaN); + + const [element, setElement] = useState(null); + const [elementWidth, setElementWidth] = useState(Number.NaN); + + const onResizeElementRef = useCallback(() => { + setElementRefWidth(elementRef.current?.clientWidth ?? Number.NaN); + }, []); + + const onResizeElement = useCallback(() => { + setElementWidth(element?.clientWidth ?? Number.NaN); + }, [element?.clientWidth]); + + useResizeObserver(elementRef, enabled ? onResizeElementRef : undefined); + useResizeObserver(element, enabled ? onResizeElement : undefined); + + return ( + <> +

Resize the window to update the width of the elements

+
+ Enabled: {enabled.toString()};
+ Width: {elementRefWidth}; +
+
+ Enabled: {enabled.toString()};
+ Width: {elementWidth}; +
+ + + ); }, }; diff --git a/src/hooks/useResizeObserver/useResizeObserver.ts b/src/hooks/useResizeObserver/useResizeObserver.ts index e1278de..2b76980 100644 --- a/src/hooks/useResizeObserver/useResizeObserver.ts +++ b/src/hooks/useResizeObserver/useResizeObserver.ts @@ -1,5 +1,6 @@ import { useEffect } from 'react'; import { unref, type Unreffable } from '../../utils/unref/unref.js'; +import { useRefValue } from '../useRefValue/useRefValue.js'; /** * This hook allows you to add a ResizeObserver for an element and remove it @@ -10,8 +11,10 @@ import { unref, type Unreffable } from '../../utils/unref/unref.js'; */ export function useResizeObserver( target: Unreffable, - callback: ResizeObserverCallback, + callback?: ResizeObserverCallback | undefined, ): void { + const callbackRef = useRefValue(callback); + useEffect(() => { const element = unref(target); @@ -19,11 +22,14 @@ export function useResizeObserver( return; } - const resizeObserverInstance = new ResizeObserver(callback); + const resizeObserverInstance = new ResizeObserver((entries, observer) => { + callbackRef.current?.(entries, observer); + }); + resizeObserverInstance.observe(element); return () => { resizeObserverInstance.disconnect(); }; - }, [target, callback]); + }, [target, callbackRef]); }