React -- useSize Hook 封装

React -- useSize Hook 封装

在开发React应用时,经常需要响应元素尺寸的变化,以提供更好的用户体验。本文将介绍如何封装一个自定义的useSize Hook,它可以监听某个元素的大小变化并返回其宽高。

背景知识

在React中,自定义Hook是一种重用状态逻辑的机制。useSize Hook将返回所观察元素的宽度和高度。

使用useState和useLayoutEffect

引入useStateuseLayoutEffect钩子。useState用来存储元素的宽度和高度,而useLayoutEffect用来订阅尺寸变化。

响应尺寸变化

通过ResizeObserver API,可以监听元素尺寸的变化。当被监听元素尺寸发生变化时,ResizeObserver将执行一个回调函数,在这个回调函数中,用setState更新元素的尺寸信息。

清理工作

为了避免内存泄漏,需要在useLayoutEffect的清理函数中断开ResizeObserver的监听。

完整的 Hook 实现

下面是useSize Hook 的完整代码实现:

jsx 复制代码
import { useState, useLayoutEffect } from 'react';
import ResizeObserver from 'resize-observer-polyfill';

function useSize(target) {
  const [state, setState] = useState(() => {
    return {
      width: target ? target.clientWidth : 0,
      height: target ? target.clientHeight : 0,
    };
  });

  useLayoutEffect(() => {
    if (!target) {
      return () => {};
    }

    const resizeObserver = new ResizeObserver(entries => {
      entries.forEach(entry => {
        setState({
          width: entry.target.clientWidth,
          height: entry.target.clientHeight,
        });
      });
    });

    resizeObserver.observe(target);

    return () => {
      resizeObserver.disconnect();
    };
  }, [typeof target === 'function' ? undefined : target]);

  return state;
}

export default useSize;

这个Hook将返回一个包含widthheight属性的对象,且会在被观察元素的尺寸变化时更新这两个属性。结合实际情况,你可以很容易地将这个Hook集成到你的React组件中。

使用方式

你可以在组件中调用useSize,并传递一个DOM元素引用(ref)作为参数。这个Hook将返回该元素的宽度和高度。

jsx 复制代码
  const chartRef = useRef(null);
  const size = useSize(chartRef.current);

小结

useSize Hook 提供了一种简洁而又高效的方式来监听和响应React元素的尺寸变化。使用这种模式可以减少冗余代码,并提高组件的可维护性。

相关推荐
张元清10 分钟前
React useEventSource Hook:自带断线重连的 Server-Sent Events (2026)
javascript·react.js
光影少年11 分钟前
RN 网络请求:Fetch / Axios 封装、超时、拦截器
前端·react native·react.js
学习星球24 分钟前
Vue 3 实战:拆解 RealWorld 项目
前端·vue.js
铁皮饭盒37 分钟前
网页端, 6.5MB人脸识别模型, 谷歌框架, 又快又准
前端·javascript·后端
xiaohaiAIgeo40 分钟前
【2026年】ASHRAE 110与EN 14175通风柜测试标准对比:进口与国产品牌性能差距
java·前端·数据库·科普知识
自进化Agent智能体1 小时前
Hermes 工具与工具集——Hermes 的内置能力
javascript
用户2930750976691 小时前
TypeScript 必考题:Type 与 Interface 全面对比
前端
hunterandroid1 小时前
[鸿蒙从零到一] HarmonyOS 媒体能力实战:图片、音频与视频处理
前端
打呵欠的猫1 小时前
我让 AI 封装了一个 ImageUpload 组件,它设计的 5 层校验链路比我想的周全
前端·ai编程
AlexMaybeBot1 小时前
躺在沙发上开发 Openclaw 的移动端APP
前端·flutter