|
1 | 1 | import type { RefObject } from 'react'; |
2 | 2 |
|
3 | | -import { useEffect, useState } from 'react'; |
| 3 | +import { useState } from 'react'; |
4 | 4 |
|
5 | 5 | import { getElement, isTarget } from '@/utils/helpers'; |
6 | 6 |
|
7 | 7 | import type { StateRef } from '../useRefState/useRefState'; |
8 | 8 |
|
| 9 | +import { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect/useIsomorphicLayoutEffect'; |
9 | 10 | import { useRefState } from '../useRefState/useRefState'; |
10 | 11 |
|
11 | 12 | /** The element size value type */ |
@@ -59,23 +60,32 @@ export interface UseElementSize { |
59 | 60 | */ |
60 | 61 | export const useElementSize = ((...params: any[]) => { |
61 | 62 | const target = (isTarget(params[0]) ? params[0] : undefined) as UseElementSizeTarget | undefined; |
62 | | - const initialValue = (target ? params[1] : params[0]) as UseElementSizeTarget | undefined; |
| 63 | + const initialValue = (target ? params[1] : params[0]) as UseElementSizeValue | undefined; |
63 | 64 |
|
64 | 65 | const [size, setSize] = useState(initialValue ?? { width: 0, height: 0 }); |
65 | 66 | const internalRef = useRefState<Element>(); |
66 | 67 |
|
67 | | - useEffect(() => { |
68 | | - if (!target && !internalRef.current) return; |
| 68 | + useIsomorphicLayoutEffect(() => { |
69 | 69 | const element = (target ? getElement(target) : internalRef.current) as Element; |
70 | 70 |
|
71 | 71 | if (!element) return; |
72 | 72 |
|
73 | | - const observer = new ResizeObserver(([entry]) => { |
74 | | - const { width, height } = entry.contentRect; |
75 | | - setSize({ width, height }); |
76 | | - }); |
| 73 | + const callback = () => { |
| 74 | + const rect = element.getBoundingClientRect(); |
| 75 | + setSize((prev) => { |
| 76 | + if (prev.width !== rect.width || prev.height !== rect.height) { |
| 77 | + return { |
| 78 | + width: rect.width, |
| 79 | + height: rect.height |
| 80 | + }; |
| 81 | + } |
| 82 | + return prev; |
| 83 | + }); |
| 84 | + }; |
77 | 85 |
|
78 | | - if (element) observer.observe(element); |
| 86 | + const observer = new ResizeObserver(callback); |
| 87 | + observer.observe(element); |
| 88 | + callback(); |
79 | 89 |
|
80 | 90 | return () => { |
81 | 91 | observer.disconnect(); |
|
0 commit comments