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

设计获取文档高度和宽度函数时遇到的问题

解决useWindowSize初始值无法获取body.offsetHeight的问题

问题原因

组件初始化时,useState的初始值是在组件挂载前计算的,这时候DOM树可能还没完全渲染完毕,document.body的内容还没加载或渲染完成,导致offsetHeight返回空值(比如0),看起来函数“无法正常工作”。

  • window.innerHeight是浏览器视口高度,不受DOM渲染状态影响,所以初始时能拿到有效值。
  • 窗口resize触发时,DOM已经完全渲染完成,body.offsetHeight已经正确计算出文档整体高度,因此能正常返回。

修正后的代码

把初始尺寸的计算移到useEffect中,确保DOM渲染完成后再获取真实的文档高度,同时复用尺寸计算逻辑:

function useWindowSize() {
    const [size, setSize] = useState([0, 0]); // 先设占位初始值

    useEffect(() => {
        // 抽离尺寸计算逻辑,复用初始和resize场景
        const calculateSize = () => {
            setSize([document.body.offsetHeight, document.body.offsetWidth]);
        };

        // 组件挂载时立即计算一次初始尺寸
        calculateSize();

        let timeoutId = null;
        const resizeListener = () => {
            clearTimeout(timeoutId);
            timeoutId = setTimeout(calculateSize, 150);
        };

        window.addEventListener("resize", resizeListener);
        return () => {
            window.removeEventListener("resize", resizeListener);
            clearTimeout(timeoutId); // 清理定时器,避免内存泄漏
        };
    }, []); // 空依赖数组,确保只执行一次挂载逻辑

    return size;
}

额外说明

如果需要在DOM更新后立即同步获取尺寸(比如避免布局抖动),可以把useEffect换成useLayoutEffect,它会在DOM变更完成后同步执行,比useEffect的异步执行时机更早。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 19:06:20