usehooks-ts icon indicating copy to clipboard operation
usehooks-ts copied to clipboard

[BUG] useResizeObserver when component dom remove and rerender ( like dialog ), size not update

Open hxdyj opened this issue 6 months ago • 0 comments

Describe the bug

useResizeObserver when component dom remove and rerender ( like dialog ), size not refresh

To Reproduce

windows chrome

Expected behavior

when useResizeObserver ref dom remove and while readd to document need update size. or export creatResizeObserver and destroyResizeObserver function give to developer to control. like below:

function useResizeObserver(options) {
	const { ref, box = "content-box" } = options;
	const [{ width, height }, setSize] = useState(initialSize);
	const isMounted = useIsMounted();
	const previousSize = useRef({ ...initialSize });
	const onResize = useRef(void 0);
	onResize.current = options.onResize;
	const observerRef = useRef(null)
	const createResizeObserver = useCallback(() => {
		if (!ref.current)
			return;
		if (typeof window === "undefined" || !("ResizeObserver" in window))
			return;
		observerRef.current = new ResizeObserver(([entry]) => {
			const boxProp = box === "border-box" ? "borderBoxSize" : box === "device-pixel-content-box" ? "devicePixelContentBoxSize" : "contentBoxSize";
			const newWidth = extractSize(entry, boxProp, "inlineSize");
			const newHeight = extractSize(entry, boxProp, "blockSize");
			const hasChanged = previousSize.current.width !== newWidth || previousSize.current.height !== newHeight;
			if (hasChanged) {
				const newSize = { width: newWidth, height: newHeight };
				previousSize.current.width = newWidth;
				previousSize.current.height = newHeight;
				if (onResize.current) {
					onResize.current(newSize);
				} else {
					if (isMounted()) {
						setSize(newSize);
					}
				}
			}
		});
		observerRef.current.observe(ref.current, { box });
	}, [isMounted, observerRef, box, ref])

	const destroyResizeObserver = useCallback(() => {
		if (observerRef.current) {
			observerRef.current.disconnect();
			previousSize.current = initialSize;
			observerRef.current = null;
		}
	}, [observerRef])

	useEffect(() => {
		createResizeObserver()
		return () => {
			destroyResizeObserver()
		}
	}, [box, ref, isMounted]);

	return { width, height, createResizeObserver, destroyResizeObserver };  // Notice: here add  createResizeObserver, destroyResizeObserver 
}

Additional context

No response

hxdyj avatar Aug 20 '24 05:08 hxdyj