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

React中如何使用useRef动态更新组件height属性?

解决方案

核心问题说明

  • 初始化阶段DOM尚未完成挂载,ref未绑定真实元素,直接读取offsetHeight会得到undefined
  • tab切换后React状态更新是异步批量执行的,直接读取DOM拿到的是上一个tab的内容高度,不是最新渲染的内容高度
  • 未在DOM更新完成的时机触发高度重新计算

完整实现代码

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

function App() {
  const [tab, setTab] = useState(0);
  // 绑定内层tab内容容器的ref
  const contentRef = useRef(null);
  // 存储动态计算的容器高度
  const [height, setHeight] = useState(0);

  const switchTab = (id) => {
    setTab(id);
  };

  // 监听tab变化,DOM更新完成后重新计算内容高度
  useEffect(() => {
    if (contentRef.current) {
      setHeight(contentRef.current.offsetHeight);
    }
  }, [tab]);

  return (
    <div
      style={{
        margin: '100px auto',
        backgroundColor: 'pink',
        width: '400px',
        overflow: 'hidden',
        height: `${height}px`, // 绑定动态计算的高度
        transition: 'height 0.3s' // 可选:增加高度过渡动画,交互更流畅
      }}
    >
      {/* 内层内容容器绑定ref,用于读取实际内容高度 */}
      <div ref={contentRef}>
        {tab === 0 && (
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            <h2>Tab 1</h2>
            <input />
            <button onClick={() => switchTab(1)}>Go to tab 2</button>
            <p>Some text here</p>
          </div>
        )}
        {tab === 1 && (
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            <h2>Tab 2</h2>
            <input />
            <button onClick={() => switchTab(0)}>Go to tab 1</button>
            <button onClick={() => switchTab(2)}>Go to tab 3</button>
            <p>
              Some more text here. Some more text here. Some more text here. Some more text here.
              Some more text here. Some more text here. Some more text here
            </p>
          </div>
        )}

        {tab === 2 && (
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            <h2>Tab 3</h2>
            <input />
            <button onClick={() => switchTab(0)}>Go to tab 1</button>
            <button onClick={() => switchTab(1)}>Go to tab 2</button>
          </div>
        )}
      </div>
    </div>
  );
}

实现逻辑说明

  1. 将ref绑定到未固定高度的内层内容容器,而非外层需要设置高度的容器
  2. 依赖tab状态作为useEffect的触发条件,useEffect会在DOM更新完成后执行,此时读取到的contentRef高度就是当前tab内容的真实高度
  3. 读取高度前增加非空判断,避免ref未挂载时读取属性报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 15:36:03