Skip to content

useSize

作用

监听 DOM 节点尺寸变化的 Hook

原理

通过 useRef 创建一个 ResizeObserver 实例,监听 DOM 节点尺寸变化,当节点尺寸变化时,更新 size 的值

源码

ts
import ResizeObserver from 'resize-observer-polyfill'
import useRafState from '../useRafState'
import type { BasicTarget } from '../utils/domTarget'
import { getTargetElement } from '../utils/domTarget'
import useIsomorphicLayoutEffectWithTarget from '../utils/useIsomorphicLayoutEffectWithTarget'

type Size = { width: number; height: number }

function useSize(target: BasicTarget): Size | undefined {
  const [state, setState] = useRafState<Size | undefined>(() => {
    // 获取目标元素的宽高
    const el = getTargetElement(target)
    return el ? { width: el.clientWidth, height: el.clientHeight } : undefined
  })

  // 监听目标元素的宽高变化
  useIsomorphicLayoutEffectWithTarget(
    () => {
      // 获取目标元素
      const el = getTargetElement(target)

      if (!el) {
        return
      }

      // 创建 ResizeObserver 实例
      const resizeObserver = new ResizeObserver((entries) => {
        // 更新目标元素的宽高
        entries.forEach((entry) => {
          const { clientWidth, clientHeight } = entry.target
          setState({ width: clientWidth, height: clientHeight })
        })
      })
      // 监听目标元素的宽高变化
      resizeObserver.observe(el)

      // 销毁 ResizeObserver 实例
      return () => {
        resizeObserver.disconnect()
      }
    },
    [],
    // 监听的目标元素
    target,
  )

  return state
}

export default useSize

如有转载或 CV 的请标注本站原文地址