监听DOM元素高度变化

场景

需要根据某个DOM元素的高度,控制另一个DOM元素的显隐。通过回调形式的ref能在首次渲染时获取到该节点的实际高度,但是如果这个节点的高度动态改变,则不能实时监听到该节点的高度

参考链接:https://legacy.reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node

import React, { useState, useCallback } from "react";
import ReactDOM from "react-dom";

function MeasureExample() {
  const [list, setList] = useState(["1"]);
  const [height, setHeight] = useState(0);

  const measuredRef = useCallback((node) => {
    if (node !== null) {
      setHeight(node.getBoundingClientRect().height);
    }
  }, []);

  return (
    <>
      {height > 30 ? <div>高度超过30px</div> : null}
      <div ref={measuredRef}>
        {list.map((r) => (
          <div>{r}</div>
        ))}
      </div>
      <button
        onClick={() => {
          setList([...list, 3]);
        }}
      >
        增加
      </button>
    </>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<MeasureExample />, rootElement);

请添加图片描述

点击增加时,并不能监听到该节点高度的变化,不会显示“高度超过30px”这句话

请添加图片描述

解决

通过ResizeObserver监听DOM元素的高度变化

import React, { useState, useRef, useEffect } from "react";
import ReactDOM from "react-dom";

function MeasureExample() {
  const [list, setList] = useState(["1"]);
  const [show, setShow] = useState(false);
  const demoRef = useRef(null);

  useEffect(() => {
    const resize = new ResizeObserver((e) => {
      if (!Array.isArray(e) || !e.length) return;
      for (const ent of e) {
        const height = ent.contentRect.height;
        if (height > 30) {
          setShow(true);
        } else {
          setShow(false);
        }
      }
    });

    if (demoRef.current) {
      resize.observe(demoRef.current);
    }
    
    return () => {
      if (demoRef.current) {
        resize.unobserve(demoRef.current);
      }
    };
  }, []);

  return (
    <>
      {show ? <div>高度超过30px</div> : null}
      <div ref={demoRef}>
        {list.map((r) => (
          <div>{r}</div>
        ))}
      </div>
      <button
        onClick={() => {
          setList([...list, 3]);
        }}
      >
        增加
      </button>
    </>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<MeasureExample />, rootElement);

请添加图片描述

点击增加时会监听到DOM高度的变化,从而显示“高度超过30px”这句话

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值