如何在React中获取每个子组件/元素的高度?
如何在React组件中获取子元素的DOM高度(仅访问child对象场景)
要实现这个需求,我们需要通过克隆子元素并注入ref的方式,将每个子元素的DOM节点收集起来,之后就能在useLayoutEffect中获取其高度。具体实现如下:
完整代码示例
import React, { useLayoutEffect, Children, useRef } from "react"; const Something = ({ children }) => { // 创建ref数组存储每个子元素的DOM节点 const childRefs = useRef([]); useLayoutEffect(() => { // 遍历ref数组,打印每个子元素的高度 childRefs.current.forEach((ref) => { if (ref) { console.log("子元素高度:", ref.offsetHeight); } }); }, [children]); // 依赖项加入children,确保子元素变化时重新执行 // 克隆每个子元素,注入ref到childRefs数组 const childrenWithRefs = Children.map(children, (child, index) => { return React.cloneElement(child, { ref: (node) => { childRefs.current[index] = node; } }); }); return <div>{childrenWithRefs}</div>; }; const App = () => { return ( <Something> <div style={{ height: "100px" }}>a</div> <div style={{ height: "150px" }}>b</div> <div style={{ height: "170px" }}>c</div> </Something> ); }; export default App;
关键逻辑说明
- ref数组收集DOM节点:使用
useRef创建一个数组childRefs,用来存储每个子元素对应的DOM节点。 - 克隆子元素注入ref:通过
Children.map遍历所有子元素,用React.cloneElement为每个子元素添加ref属性,将DOM节点存入childRefs.current对应索引的位置。 - 在useLayoutEffect中获取高度:
useLayoutEffect会在DOM更新完成后立即执行,此时可以安全访问DOM节点的高度属性(这里用offsetHeight,也可以根据需求使用clientHeight)。 - 依赖项设置:将
children加入依赖数组,确保当子元素发生变化时,能重新收集DOM节点并计算高度。
注意事项
- 如果子元素是自定义组件,需要确保该组件使用
React.forwardRef转发ref,否则无法获取到其内部的DOM节点。 - 若存在条件渲染的子元素,需注意
childRefs数组中可能出现空值,因此在遍历的时候要做存在性判断。
内容的提问来源于stack exchange,提问作者basickarl
相关产品推荐
相关产品推荐

