You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用React Hooks获取容器宽高是否有其他更简单的实现方法?

实现方案

你原有代码的核心问题在于:普通DOM元素本身不会触发resize事件(仅window对象支持该事件)、useEffect未加依赖数组导致反复绑定/解绑事件、获取的是窗口尺寸而非容器尺寸。我们可以用标准ResizeObserver API实现需求,这是目前监听元素尺寸变化的最优方案,完整可运行代码如下:

import { useState, useRef, useEffect } from 'react';

// 防抖工具函数
function debounce(fn, ms) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, ms);
  };
}

export default function App() {
  const containerRef = useRef(null);
  const [dimensions, setDimensions] = useState({
    height: 0,
    width: 0
  });

  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;

    // 初始化时直接获取容器尺寸,解决首次渲染无正确值的问题
    const updateDimensions = () => {
      const { width, height } = container.getBoundingClientRect();
      setDimensions({ width, height });
    };
    updateDimensions();

    // 用ResizeObserver监听容器本身的尺寸变化,替代无效的元素resize事件监听
    const debouncedUpdate = debounce(updateDimensions, 300);
    const resizeObserver = new ResizeObserver(debouncedUpdate);
    resizeObserver.observe(container);

    // 清理逻辑,组件卸载时断开监听避免内存泄漏
    return () => {
      resizeObserver.disconnect();
    };
  }, []); // 空依赖数组,仅在组件挂载时执行一次

  // 此处可直接使用dimensions的宽高完成业务逻辑
  console.log('当前容器尺寸:', dimensions);

  return (
    <div className='container' ref={containerRef}>
      My Container
    </div>
  );
}

方案说明

  • 解决了获取容器自身尺寸的需求:通过getBoundingClientRect直接读取容器宽高,ResizeObserver专门监听容器本身的尺寸变化,和窗口尺寸完全解耦
  • 解决了首次渲染崩溃的问题:组件挂载后会立即执行一次尺寸更新逻辑,第一时间拿到正确的容器尺寸,不需要依赖错误的窗口初始值
  • 符合简洁的最新实现规范:用useRef绑定DOM元素,不需要通过getElementById查询DOM,符合React最佳实践,ResizeObserver是原生标准API,无需引入第三方依赖

内容的提问来源于stack exchange,提问作者Bhushan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 17:54:02