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

React中获取元素宽高遇undefined问题求助

问题分析与解决方案

核心问题原因

  • State更新异步特性:setcircleWidth是异步操作,调用后不会立刻更新circleWidth的值,你在getWidth里直接console.log(circleWidth),打印的永远是调用前的旧值(也就是初始的undefined)。
  • 元素渲染时机:首次页面加载时,空依赖的useEffect执行时,目标元素可能还没完成样式渲染(比如CSS还没计算完毕),导致getBoundingClientRect拿不到正确宽高;而修改代码热重载时,元素已经完成渲染,所以能正常获取值。

修正后的代码

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

// 组件内部代码
const circleRef = useRef(null);
const [circleWidth, setCircleWidth] = useState(0);

const getWidth = () => {
  if (!circleRef.current) return;
  const positionInfo = circleRef.current.getBoundingClientRect();
  const width = positionInfo.width;
  setCircleWidth(width);
};

// 监听circleWidth的变化,更新后再打印
useEffect(() => {
  console.log('当前circleWidth:', circleWidth);
}, [circleWidth]);

// 确保元素挂载且样式渲染完成后再获取宽高
useEffect(() => {
  // 用requestAnimationFrame保证样式计算完成
  const rafId = requestAnimationFrame(() => {
    getWidth();
  });

  // 清理函数
  return () => cancelAnimationFrame(rafId);
}, []);

// JSX部分,给目标元素绑定ref
return (
  <div className="testimonial-circle-left" ref={circleRef}>
    {/* 元素内容 */}
  </div>
);

额外优化点

  • 替换document.querySelector:React中优先用useRef绑定元素,更符合组件化思想,还能避免全局选择器带来的潜在冲突。
  • 处理窗口 resize:如果元素宽高会随窗口变化,可添加resize监听实时更新:
    useEffect(() => {
      const handleResize = () => {
        getWidth();
      };
      window.addEventListener('resize', handleResize);
      return () => window.removeEventListener('resize', handleResize);
    }, []);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 21:18:19