0

0

如何正确获取完整文档高度与宽度的 React 自定义 Hook 教程

碧海醫心

碧海醫心

发布时间:2025-12-30 12:34:02

|

735人浏览过

|

来源于php中文网

原创

如何正确获取完整文档高度与宽度的 React 自定义 Hook 教程

本文详解如何在 react 中设计一个可靠的 `usewindowsize` 自定义 hook,准确获取整个文档(而非仅视口)的高度和宽度,并解决初始化时 `document.body.offsetheight` 返回 0 或无效值的核心问题。

在 React 中,window.document.body.offsetHeight 用于获取整个 HTML 文档内容区域的实际渲染高度(含滚动内容),而 window.innerHeight 仅代表当前可视区域(viewport)高度。许多开发者在封装 useWindowSize Hook 时发现:若初始 state 直接使用 document.body.offsetHeight,往往得到 0 或远小于预期的值——这是因为组件首次挂载时,DOM 可能尚未完成布局计算(尤其是当 <body> 内容依赖异步数据、CSS 加载或动态渲染时),导致 offsetHeight 尚未就绪。

根本原因在于:useState 的初始值在组件函数执行阶段即被求值,此时 React 还未将 DOM 提交到页面,document.body 虽存在,但其子元素可能尚未完成样式计算与布局(layout)。而 resize 事件触发时,浏览器已处于稳定渲染状态,因此后续调用 offsetHeight 总是有效的。

✅ 正确解法:延迟初始化 + 主动触发更新
我们不应在 useState 中直接读取 offsetHeight,而应借助 useEffect(它在 DOM 渲染后执行)手动触发一次尺寸采集:

import { useState, useEffect } from 'react';

function useDocumentSize() {
  const [size, setSize] = useState<[number, number]>([0, 0]);

  useEffect(() => {
    let timeoutId: NodeJS.Timeout | null = null;

    const updateSize = () => {
      clearTimeout(timeoutId!);
      timeoutId = setTimeout(() => {
        // ✅ 安全读取:此时 DOM 已布局完成
        const height = document.body.offsetHeight;
        const width = document.body.offsetWidth;
        setSize([height, width]);
      }, 150); // 防抖,避免频繁重绘
    };

    // ? 关键:挂载后立即执行一次,确保初始值准确
    updateSize();

    // 监听窗口大小变化
    window.addEventListener('resize', updateSize);

    return () => {
      window.removeEventListener('resize', updateSize);
      if (timeoutId) clearTimeout(timeoutId);
    };
  }, []); // ? 空依赖数组:仅在挂载/卸载时运行

  return size;
}

? 使用示例:

DreamStudio
DreamStudio

SD兄弟产品!AI 图像生成器

下载
function App() {
  const [docHeight, docWidth] = useDocumentSize();

  return (
    <div>
      <p>文档总高度: {docHeight}px</p>
      <p>文档总宽度: {docWidth}px</p>
      {/* 页面内容... */}
    </div>
  );
}

⚠️ 注意事项:

  • 不要用 innerHeight/innerWidth 替代:它们反映视口尺寸,无法代表长页面的完整文档高度;
  • 确保 <body> 有明确内容与样式:若 body 为空或 height: 0,offsetHeight 必然为 0;可添加 min-height: 100vh 等兜底样式;
  • 服务端渲染(SSR)兼容性:该 Hook 仅适用于浏览器环境,在 SSR 中需加 typeof window !== 'undefined' 判断,或返回默认值 [0, 0];
  • 性能优化:防抖 150ms 是合理折中;如需更高实时性,可改用 ResizeObserver(但需注意兼容性)。

? 进阶建议:对于更健壮的尺寸监听,推荐结合 ResizeObserver 观察 document.body 元素本身,避免依赖全局 resize 事件,从而提升精度与响应速度。但对大多数场景,上述 useEffect + resize + 手动触发 方案简洁、可靠、兼容性好,是推荐的最佳实践。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

6533

2023.07.31

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

3347

2024.08.14

网页undefined啥意思
网页undefined啥意思

本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

1695

2025.12.25

JavaScript中的typeof用法
JavaScript中的typeof用法

在JavaScript中,typeof是一个用来确定给定变量的数据类型的操作符。可以用来确定一个变量是字符串、数字、布尔值、函数、对象或undefined的数据类型。更多关于typeof用法相关文章,详情请看本专题下面的文章,php中文网欢迎大家前来学习。

770

2023.11.23

DOM是什么意思
DOM是什么意思

dom的英文全称是documentobjectmodel,表示文件对象模型,是w3c组织推荐的处理可扩展置标语言的标准编程接口;dom是html文档的内存中对象表示,它提供了使用javascript与网页交互的方式。想了解更多的相关内容,可以阅读本专题下面的文章。

4356

2024.08.14

PHP 高并发与性能优化
PHP 高并发与性能优化

本专题聚焦 PHP 在高并发场景下的性能优化与系统调优,内容涵盖 Nginx 与 PHP-FPM 优化、Opcode 缓存、Redis/Memcached 应用、异步任务队列、数据库优化、代码性能分析与瓶颈排查。通过实战案例(如高并发接口优化、缓存系统设计、秒杀活动实现),帮助学习者掌握 构建高性能PHP后端系统的核心能力。

114

2025.10.16

PHP 数据库操作与性能优化
PHP 数据库操作与性能优化

本专题聚焦于PHP在数据库开发中的核心应用,详细讲解PDO与MySQLi的使用方法、预处理语句、事务控制与安全防注入策略。同时深入分析SQL查询优化、索引设计、慢查询排查等性能提升手段。通过实战案例帮助开发者构建高效、安全、可扩展的PHP数据库应用系统。

99

2025.11.13

JavaScript 性能优化与前端调优
JavaScript 性能优化与前端调优

本专题系统讲解 JavaScript 性能优化的核心技术,涵盖页面加载优化、异步编程、内存管理、事件代理、代码分割、懒加载、浏览器缓存机制等。通过多个实际项目示例,帮助开发者掌握 如何通过前端调优提升网站性能,减少加载时间,提高用户体验与页面响应速度。

36

2025.12.30

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.9万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

CSS教程
CSS教程

共754课时 | 43.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号