在 React 中通过 getBoundingClientRect 接收元素的尺寸

2024-01-26

我想以可靠的方式找出 DOM 元素的尺寸。

我的考虑是使用 getBoundingClientRect 来实现此目的。

  const elementRef = useRef<HTMLUListElement | null>(null);
  const [dimensions, setDimensions] = useState<DOMRect | undefined>();

  const element: HTMLUListElement | null = elementRef.current;

  /**
   * Update dimensions state.
   */
  const updateDimensions = useCallback(() => {
    if (!element) return;

    setDimensions(element.getBoundingClientRect());
  }, [element, setDimensions]);

  /**
   * Effect hook to receive dimensions changes.
   */
  useEffect(() => {
    if (element) {
      updateDimensions();
    }
  }, [element, updateDimensions]);

这种方法的问题是 useEffect 只对 elementRef.current 做出反应,而不对 rect 更改做出反应。显然,浏览器中组件的绘制尚未完成,因为尺寸始终为 0。

如果我在 useEffect 之外完成所有操作,那么它就会起作用。在控制台中,我看到 2 次值为 0,然后是正确的尺寸。

与useEffect:

外部使用效果:

但是,我想保存状态中的维度,为此我需要 useEffect。

如何使用 getBoundingClientRect 实现此目的,或者是否有其他方法可以实现此目的?

SOLUTION

这不是自己反应的问题。这是 ionic V5 React 中的一个错误。

通常你可以这样做:

https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node

但这里有一个问题:

https://github.com/ionic-team/ionic/issues/19770 https://github.com/ionic-team/ionic/issues/19770

我的解决方案是使用:https://github.com/que-etc/resize-observer-polyfill https://github.com/que-etc/resize-observer-polyfill

import { RefCallback, useCallback, useState } from 'react';
import ResizeObserver from 'resize-observer-polyfill';


export function useDimensions(): [RefCallback<HTMLElement | null>, DOMRect | undefined] {
  const [dimensions, setDimensions] = useState<DOMRect | undefined>();

  const ref: RefCallback<HTMLElement | null> = useCallback((node: HTMLElement | null) => {
    if (node) {
      setDimensions(node.getBoundingClientRect().toJSON());

      const resizeObserver = new ResizeObserver((entries) => {
        if (entries.length) {
          setDimensions(entries[0].target.getBoundingClientRect().toJSON());
        }
      });

      resizeObserver.observe(node);

      return () => {
        resizeObserver.unobserve(node);
        resizeObserver.disconnect();
      };
    }
  }, []);

  return [ref, dimensions];
}

您可以使用 callBackRef 来实现所需的行为:

import React, { useCallback, useState } from "react";

export default function App() {
  const [dimensions, setDimensions] = useState(null);

  const callBackRef = useCallback(domNode => {
    if (domNode) {
      setDimensions(domNode.getBoundingClientRect());
    }
  }, []);

  return (
    <div>
      <h1 ref={callBackRef}>Measure me</h1>
    </div>
  );
}`
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 React 中通过 getBoundingClientRect 接收元素的尺寸 的相关文章

随机推荐

  • 无法使用 DBeaver 连接到 MariaDB

    我刚刚在 Ubuntu 18 04 上安装了 MariaDB 10 1 29 从命令行我可以使用 sudo 连接 sudo mysql u root p 但并非没有 sudo 另外 如果我尝试通过连接到数据库DBeaver https db
  • 需要更好的方法使用 jquery 验证插件来验证 ASP.NET 复选框吗?

    Problem 我想使用 jquery 验证插件来验证一些 ASP NET 复选框 位于 http bassistance de jquery plugins jquery plugin validation http bassistanc
  • Windows 上 JDK 8 的默认 -Xss 值

    Oracle 说在 Windows 上 http docs oracle com javase 8 docs technotes tools windows java html Xsssize 默认值取决于虚拟内存 我如何找出给定 Orac
  • Windows 上的“docker-compose up”失败,Mysql 容器步骤出现错误

    我正在尝试使用 docker 和 docker compose yml 在 phpstorm 中设置在 Windows 10 上进行 php 开发的环境 但在 Mysql 设置步骤中遇到了一些错误 找不到问题 这是我的 docker com
  • 连接字符串的节点内存使用情况

    我有以下代码来测试节点虚拟机的内存使用情况 setInterval gt console log process memoryUsage 1000 gt const MAXTIMES 10000000 let a gt let res fo
  • 更新 Android SDK 工具 REV 22 后出现错误“无法解析 L 的超类”

    昨天项目还好 但是今天更新Sdk工具和ADT REV 22 时 运行项目时出现 无法解析L的超类 之类的错误 我的项目使用 ActionbarSherlock 和 SlidingMenu 我已经尝试过 将外部 jar 复制到我的项目的 li
  • 为什么 pthread-win32 中主线程比工作线程慢?

    void worker void int clk clock float val 0 for int i 0 i 100000000 i val sin i printf val f n val printf worker d ms n c
  • 如何针对 GitHub 问题上的特定分支

    我想知道是否可以目标问题到存储库的特定分支 使用案例 我有一个有 1 个主分支的仓库 和2个开发分支 A 和 B 根据问题的不同 其他分支会从 A 分支和 B 分支中生长出来 我已经知道可以通过 关键字和问题编号来引用问题提交 但我希望将其
  • 从 GitLab 运行程序/管道中创建版本

    随着 2019 年 1 月 Gitlab 11 7 的发布 我们获得了新的关键功能为您的项目发布版本 https about gitlab com 2019 01 22 gitlab 11 7 released publish releas
  • 如何本地化活动记录错误消息

    我试图找出如何本地化我的 Rails 应用程序中的错误项目名称 当用户使用不正确的数据注册时会出现该错误项目名称 我想出了如何覆盖消息 但不覆盖消息的名称 例如 password 登录 电子邮件 de activerecord errors
  • PowerShell - 在特定范围内执行脚本块

    我正在尝试在 Powershell 中实现像 BDD 框架一样的 RSpec Jasmine 或者至少研究制作一个框架的潜在问题 目前 我在实现简单的前后功能时遇到问题 给定 ErrorActionPreference Stop funct
  • 如何正确创建 Zend Feed?

    我已经成功创建了一个简单的 RSS 提要 但条目不断返回为未读和更新状态 并且每次我要求邮件更新提要时 从客户端删除的条目都会重新出现 我究竟做错了什么 我使用这个简单的函数来创建 rss feed public static functi
  • jquery 设置加载后的高度

    我在设置动态加载的元素的高度时遇到了一些麻烦 我用jqueryload函数将外部 动态 页面加载到当前页面上的 div cbox 中 因为这个子页面是动态的 所以我无法事先知道内容的高度是多少 我想在加载内容后获取高度 并将容器 div 的
  • Android dropbox api 需要重新验证

    在我的应用程序中 我使用 dropbox api 来保存一些文件 没问题 身份验证后 我关闭应用程序并重新启动应用程序 每次我打开应用程序时都需要重新身份验证 我希望应用程序记住我的会话 Dropbox 教程 https www dropb
  • CMake 中预期的构建失败测试

    有时最好检查某些东西是否无法构建 例如 Next line should fail to compile can t convert const iterator to iterator my new container type iter
  • 将部分参数列表传递给 do.call()

    我正在尝试编写一个函数来测试 GBM 模型的一系列超参数 我只希望 GBM 调用中的三个参数发生变化 其余的我想保持静态 do call似乎是答案 因为它接受参数列表并将它们传递给函数 然而 我不知道是否有办法 修复 一些我不想改变的论点
  • 确保启用“Google Maps Android API v2”。当我尝试实施 Google 地图时收到此错误

    我正在使用谷歌地图 但收到此错误 我做了以下事情 得到了我的 sha1 指纹 注册了我的项目并获得了我的项目密钥 我不知道如何启用 Google Maps Android API v2 因为我尝试过的所有链接都是旧的 并且 Google 已
  • 当 PHP 中的某个键被赋值时,数组是否会隐式创建?

    只是想快速验证这一点 它与我在其他语言中的直接经验不同 在其他语言中 必须首先声明数组 然后才能填充值 是的 PHP 将自动创建一个数组给定以下任何一个 foo bar foo 1 bar foo bar bar and of course
  • 更改每个像素的图像并保存到数据库

    我正在制作一个小网页游戏 我正在寻找一种方法来操作每个像素的图像并将其存储在 mysql 数据库中 准确地说 我需要能够执行以下操作 从 mysql 数据库加载图像 250 x 250px 到屏幕上 图像不可见 例如 每个像素的 alpha
  • 在 React 中通过 getBoundingClientRect 接收元素的尺寸

    我想以可靠的方式找出 DOM 元素的尺寸 我的考虑是使用 getBoundingClientRect 来实现此目的 const elementRef useRef