前端【免费下载链接】usehooks-tsReact hook library, ready to use, written in Typescript.项目地址https://gitcode.com/gh_mirrors/us/usehooks-ts点击查看免费下载导读useResizeObserver是 usehooks-ts 库中基于浏览器原生 ResizeObserver API 封装的 React Hook用于实时观测指定 DOM 元素的尺寸变化。它适用于响应式布局、图表容器自适应、编辑器高度追踪、拖拽面板尺寸同步等需要元素自身尺寸而非视口尺寸的场景。读完本文你将掌握该 Hook 的完整参数语义、返回值约定、底层实现原理、防抖优化技巧以及在不支持 ResizeObserver 的旧浏览器中如何通过 polyfill 安全接入。一、快速上手useResizeObserver接受一个包含ref的 options 对象返回被观测元素的width与height初始值为undefined。最基础的用法如下import { useRef } from react import { useResizeObserver } from usehooks-ts function Component() { const ref useRefHTMLDivElement(null) const { width 0, height 0 } useResizeObserver({ ref, box: content-box, }) return ( div ref{ref} style{{ width: 100%, resize: both, overflow: auto }} {width} x {height} /div ) }仓库中的官方演示 正是采用这一模式给目标元素挂上refHook 自动注册 ResizeObserver 并驱动组件重新渲染尺寸实时显示在元素内部。二、参数与返回值完整说明2.1 Parameters参数类型默认值说明refRefObjectTT extends HTMLElement必填要观测的元素的 refonResize(size: Size) voidundefined提供该回调后Hook 不再因尺寸变化触发重渲染而是把尺寸委托给回调处理boxborder-box \| content-box \| device-pixel-content-boxcontent-box观测使用的盒模型其中Size类型定义为{ width: number | undefined; height: number | undefined }与返回值的类型定义一致见 useResizeObserver.ts。2.2 Returns当未提供onResize可选回调时Hook 返回包含元素width和height的对象初始状态两者均为undefined源码中initialSize常量即{ width: undefined, height: undefined }。这与 测试用例 中 should return initial undefined sizes 的断言完全一致const ref { current: document.createElement(div) } const { result } renderHook(() useResizeObserver({ ref })) expect(result.current.width).toBeUndefined() expect(result.current.height).toBeUndefined()三、两种观测模式状态驱动 vs 回调驱动从 核心实现 可以看到Hook 根据是否传入onResize走两条完全不同的路径未传onResize默认每次尺寸变化都会触发内部setState驱动组件重新渲染返回的width/height即最新值。这是声明式用法适合尺寸变化频率较低、需要实时反馈的场景。传入onResizeHook 不再setState而是把新的Size对象交给回调组件渲染完全由你控制。这适合高频尺寸变化如拖拽缩放或需要把尺寸写入外部状态管理的场景。一个值得注意的实现细节是onResize被保存在useRef中并在每次渲染时同步onResize.current options.onResize因此回调始终是最新的闭包不会因组件重新渲染导致useEffect依赖变化而重复注册 Observer。此外Hook 内部用previousSizeref 记录了上一次的尺寸只有当inlineSize/blockSize真正变化时才会分发新尺寸避免了同一尺寸的重复回调const hasChanged previousSize.current.width ! newWidth || previousSize.current.height ! newHeight if (hasChanged) { const newSize: Size { width: newWidth, height: newHeight } previousSize.current.width newWidth previousSize.current.height newHeight // ...分发 }3.1 回调模式下的防抖优化在回调模式下尺寸变化往往以帧率级别高频触发ResizeObserver 的回调发生在布局之后、绘制之前。官方演示 useResizeObserver.demo.tsx 展示了与useDebounceCallback组合的推荐做法——用 200ms 的防抖把尺寸写入本地 state避免每次微小的尺寸变化都引发重渲染const onResize useDebounceCallback(setSize, 200) useResizeObserver({ ref, onResize, })useDebounceCallback实现见 useDebounceCallback.ts底层基于lodash.debounce组件卸载时会自动cancel()未执行的调用因此在回调模式下使用是安全且推荐的最佳实践。四、box 参数与底层盒模型映射box参数直接透传给observer.observe(ref.current, { box })并在回调中映射到ResizeObserverEntry上对应的尺寸数组box取值对应ResizeObserverEntry属性content-box默认contentBoxSizeborder-boxborderBoxSizedevice-pixel-content-boxdevicePixelContentBoxSize三者的语义区别content-box内容盒尺寸即元素 padding 以内的区域是最常用的默认值border-box边框盒尺寸包含 padding 与 border官方演示box: border-box即用此模式展示含边框的总尺寸device-pixel-content-box以设备像素为单位的内容盒尺寸适合需要精确到物理像素的场景如 Canvas 绘制但浏览器支持度最低。4.1 浏览器兼容性兜底extractSize不同浏览器对ResizeObserverEntry尺寸字段的实现存在差异标准规范要求borderBoxSize/contentBoxSize是数组但 Firefox 存在返回非数组的非标准行为。源码中的extractSize函数专门处理了这一兼容性问题useResizeObserver.tsfunction extractSize( entry: ResizeObserverEntry, box: BoxSizesKey, sizeType: keyof ResizeObserverSize, ): number | undefined { if (!entry[box]) { // 对于 contentBoxSize 缺失的情况回退到 contentRect 的 width/height if (box contentBoxSize) { return entry.contentRect[sizeType inlineSize ? width : height] } return undefined } return Array.isArray(entry[box]) ? entry[box][0][sizeType] : (entry[box][sizeType] as number) // 兼容 Firefox 的非标准行为 }同时尺寸读取统一使用inlineSize/blockSize对应水平/垂直方向的长度并优先取数组第一项——根据规范当元素未发生多列布局时数组只有一项。五、SSR 与卸载安全性Hook 在两个关键位置做了防御性处理SSR 安全useEffect内部首先检查typeof window undefined || !(ResizeObserver in window)任一条件成立便直接返回、不注册 Observer源码 L64-L67。因此在服务端渲染阶段Hook 会保持初始的undefined尺寸不会抛出异常。卸载安全Hook 依赖useIsMounted()实现见 useIsMounted.ts在异步回调中调用setSize前先检查组件是否已挂载避免卸载后 setState 引发的 React 警告useEffect的 cleanup 中调用observer.disconnect()释放 Observer 资源。六、Polyfill旧浏览器兼容方案useResizeObserver刻意不内置 polyfill把选择权交给使用者。原文档给出了推荐的接入方式——通过先注入再转发的封装模式在不支持ResizeObserver的浏览器如较旧版本的 Safari、IE 系列中无缝降级// useResizeObserver.ts import { ResizeObserver } from juggle/resize-observer import { useResizeObserver } from usehooks-ts if (!window.ResizeObserver) { window.ResizeObserver ResizeObserver } export { useResizeObserver }之后在你的项目中从本地封装文件导入该 Hook 即可。这种模式的优点只在window.ResizeObserver缺失时才注入 polyfill现代浏览器零开销通过 re-export 保持与原 Hook 完全一致的 API 签名业务代码无需任何改动juggle/resize-observer正是本仓库开发与测试依赖package.json测试文件 在beforeEach中也用它将window.ResizeObserver替换为 polyfill 实现以确保测试环境行为与真实浏览器一致。七、与 useScreen / useWindowSize 的定位差异在尺寸观测类 Hook 中useResizeObserver与仓库内的useScreen、useWindowSize定位互补useScreenuseScreen.ts观测的是window.screen对象即屏幕的宽高与属性与浏览器窗口大小无关useWindowSize观测的是视口/窗口尺寸响应window的resize事件useResizeObserver观测的是页面内任意 DOM 元素的尺寸粒度最细能捕获元素因内容变化、flex 布局伸缩、CSS 变换等引发的尺寸变动——这是前两者无法做到的。选择建议需要感知某个具体元素的尺寸时用useResizeObserver需要感知窗口或屏幕尺寸时用后两者。八、小结useResizeObserver以约百行 TypeScript 封装了 ResizeObserver 的全部核心语义三种盒模型选择、状态/回调双模式、Firefox 非标准行为兼容、contentRect 兜底、SSR 与卸载防护并通过不内置 polyfill 的决策保持体积轻量。配合useDebounceCallback可以优雅地应对高频尺寸变化是进行细粒度元素级响应式开发时一个开箱即用的可靠选择。// 完整最小示例带防抖的元素尺寸观测 import { useRef, useState } from react import { useDebounceCallback, useResizeObserver } from usehooks-ts export default function ResizableBox() { const ref useRefHTMLDivElement(null) const [size, setSize] useState({ width: undefined, height: undefined }) const onResize useDebounceCallback(setSize, 200) useResizeObserver({ ref, onResize }) return ( div ref{ref} style{{ border: 1px solid palevioletred, width: 100%, resize: both, overflow: auto, maxWidth: 100%, }} {size.width} x {size.height} /div ) }赞分享前端【免费下载链接】usehooks-tsReact hook library, ready to use, written in Typescript.项目地址https://gitcode.com/gh_mirrors/us/usehooks-ts点击查看免费下载相关推荐react-use 之 useMeasure基于 ResizeObserver 的响应式元素尺寸监听 Hook 实战指南react use 之 useMeasure基于 ResizeObserver 的响应式元素尺寸监听 Hook 实战指南 导读 useMeasure 是 re前端元素尺寸变化监测beautiful-react-hooks的useResizeObserver hooks完全指南元素尺寸变化监测beautiful react hooks的useResizeObserver hooks完全指南 在现代前端开发中实时监测DOM元素尺寸变前端开发工具useSize 深入解析基于 ResizeObserver 的 React DOM 尺寸监听 Hook 实现与实战useSize 深入解析基于 ResizeObserver 的 React DOM 尺寸监听 Hook 实现与实战 导读 useSize 是 ahooks本前端上一篇wxauto微信自动化完全指南如何用Python快速搭建Windows端智能微信机器人下一篇近红外光谱数据集找不到怎么办Open-Nirs-Datasets完整选数与建模指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
