实时监听容器大小变化

    1. import { useLayoutEffect, useState, useMemo, useRef } from 'react';
    2. import ResizeObserver from 'resize-observer-polyfill';
    3. declare const RectAttrTypes: ['x', 'y', 'left', 'right', 'top', 'bottom', 'width', 'height'];
    4. export type RectAttrType = typeof RectAttrTypes[number];
    5. export type EleRect = Pick<DOMRectReadOnly, RectAttrType>;
    6. const initialState: EleRect = {
    7. x: 0,
    8. y: 0,
    9. top: 0,
    10. left: 0,
    11. right: 0,
    12. width: 0,
    13. bottom: 0,
    14. height: 0,
    15. };
    16. const useResizeRect = <T extends HTMLElement>() => {
    17. const domRef = useRef<T | null>(null);
    18. const [rect, setRect] = useState<EleRect>(initialState);
    19. const observer = useMemo(() => {
    20. return new ResizeObserver((entries: any) => {
    21. if (entries[0]) {
    22. setRect(entries[0].contentRect as EleRect);
    23. }
    24. });
    25. }, [domRef]);
    26. useLayoutEffect(() => {
    27. if (domRef.current instanceof HTMLElement) {
    28. observer?.observe?.(domRef.current);
    29. }
    30. return () => {
    31. observer?.disconnect?.();
    32. };
    33. }, [domRef, observer]);
    34. return [domRef, rect] as const;
    35. };
    36. export default useResizeRect;