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