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

迭代渲染过程中如何跟踪div的动态高度增量?

解决方案

核心原因

你在map遍历中直接读取DOM高度的写法无效,是因为React的渲染流程是先同步计算完所有待渲染的JSX节点,再一次性更新到DOM树上。遍历执行的阶段属于render阶段,此时所有新的列表项都还没挂载到页面,你读到的永远是上一次渲染完成后的总高度,自然拿不到每轮迭代的增量。

推荐解决方法

方法1:使用ref回调逐个监听列表项挂载

这种方式不需要额外依赖,性能开销最小,适合自定义列表项组件的场景:

  1. 首先定义存储上一次高度的ref和跟踪容器的ref:
import { useRef } from 'react';

// 组件内部逻辑
// 存储上一次测量的容器高度
const lastHeightRef = useRef(0);
// 绑定你要跟踪高度的目标div
const trackContainerRef = useRef(null);
  1. 修改JSX部分,通过ref回调在每个列表项挂载完成后触发测量:
<div id="divtotrack" ref={trackContainerRef}>
  {items.map((item) => (
    <div 
      key={item.id}
      ref={(domNode) => {
        // 仅当列表项DOM挂载、且容器存在时执行测量
        if (!domNode || !trackContainerRef.current) return;
        const currentTotalHeight = trackContainerRef.current.clientHeight;
        // 计算本次增量
        const heightIncrement = currentTotalHeight - lastHeightRef.current;
        // 此处可执行你需要的增量处理逻辑
        console.log('当前列表项对应的高度增量:', heightIncrement);
        // 更新上一次高度存储
        lastHeightRef.current = currentTotalHeight;
      }}
    >
      {/* 注意:React自定义组件首字母必须大写,原来的<item />需要改为<Item /> */}
      <Item
        id={item.id}
        content={item.content}
      />
    </div>
  ))}
</div>

方法2:使用MutationObserver监听容器变化

如果列表项是第三方组件、或不想修改列表项相关代码,可以用MutationObserver监听容器的子节点变化,自动计算增量:

import { useEffect, useRef } from 'react';

// 组件内部逻辑
const trackContainerRef = useRef(null);
const lastHeightRef = useRef(0);

useEffect(() => {
  const container = trackContainerRef.current;
  if (!container) return;

  // 初始化记录容器初始高度
  lastHeightRef.current = container.clientHeight;

  // 创建监听器
  const observer = new MutationObserver((mutationList) => {
    // 仅当有新子节点新增时执行测量
    const hasNewNode = mutationList.some(mutation => mutation.addedNodes.length > 0);
    if (!hasNewNode) return;

    const currentTotalHeight = container.clientHeight;
    const heightIncrement = currentTotalHeight - lastHeightRef.current;
    // 处理增量逻辑
    console.log('高度增量:', heightIncrement);
    lastHeightRef.current = currentTotalHeight;
  });

  // 开启监听
  observer.observe(container, {
    childList: true, // 监听子节点变化
    subtree: true // 监听所有后代节点变化
  });

  // 组件卸载时销毁监听器
  return () => observer.disconnect();
}, []);

注意事项

  • 如果列表项内部包含异步加载的资源(比如图片、异步渲染的富文本),需要等资源加载完成后再测量高度,否则会出现增量计算不准的问题
  • 不要在render阶段(map遍历的回调函数内)直接操作或读取DOM,所有DOM相关的操作都要放在挂载完成后的回调/副作用中执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:24:03