javascript - 如何从 ReactNode 获取元素的高度和宽度?
问题描述
我有一个动态组件,我在其中将孩子作为道具传递。所以道具看起来像:
interface Props {
...some props
children: React.ReactNode
}
export default Layout({...some props, children}: Props) {...}
我需要访问组件中子元素的大小(高度和宽度)Layout
。请注意,孩子来自完全不同的组件并且是不相关的。
我可以按如下方式使用 Layout 组件:
<Layout ...some props>
<Child1 /> // I need to know the height and width of this child
<Child2 /> // as well as this child
<Child3 /> // and this child.
</Layout>
我怎样才能动态地做到这一点?我是否必须以某种方式转换ReactNode
为HTMLDivElement
?请注意,我无法将数组refs
作为道具传递到Layout
. 因为使用的页面Layout
是动态生成的。
因为很多人并不真正理解我所说的动态生成是什么意思。这意味着使用 Layout 组件的页面可以传入 x 个子级。孩子的数量是未知的,但永远不会是 0。
解决方案
您可以通过React.Children
在渲染子项之前动态构建引用列表来实现此目的。如果您有权访问子元素引用,则可以遵循以下方法。如果你不这样做,那么你可以按照底部的位。
您可以访问子元素引用
如果子组件传递它们的元素引用,您可以使用React.Children
循环遍历每个子组件并获取每个元素引用。然后在渲染子组件之前使用它来执行计算。
即这是一个关于如何检索和使用引用的非常简单的示例。
interface LayoutWrapperProps {
onMount: () => void;
}
const LayoutWrapper: React.FC<LayoutWrapperProps> = ({ onMount, children }) => {
React.useEffect(() => {
onMount();
}, [onMount]);
return <>{children}</>;
};
const Layout: React.FC = ({ children }) => {
const references = React.useRef<HTMLElement[]>([]);
React.useEffect(() => {
references.current = [];
});
function getReference(ref: HTMLElement) {
references.current = references.current.filter(Boolean).concat(ref);
}
function getHeights() {
const heights = references.current.map((ref) =>
ref?.getBoundingClientRect()
);
console.log(heights);
}
const clonedChildren = React.Children.map(children, (child) => {
return React.cloneElement(child as any, {
ref: getReference
});
});
return <LayoutWrapper onMount={getHeights}>{clonedChildren}</LayoutWrapper>;
};
如果您无权访问子元素引用
如果子组件没有将元素作为引用传递,则必须将动态子组件包装在组件中,以便我们可以获得元素引用。IE
const WrappedComponent = React.forwardRef((props, ref) => {
return (
<div ref={ref}>
{props.children}
</div>
)
});
渲染子组件时,上面获取引用的代码将起作用:
<Layout>
<WrappedComponent>
<Child1 />
</WrappedComponent>
</Layout>
推荐阅读
- c# - DataGrid 在页面上时不显示新项目
- javascript - lazyFetching 在 fullcalendar 插件中不起作用
- ssl - 如何在 heroku 上为应用创建动态子域:(例如 d1.example.com)
- python - FireFox 配置文件复制失败
- java - 进行移动自动化测试时如何处理不同的相机ID?
- ruby - 类中的命名空间方法
- bash - 如何批量创建符号链接
- php - 数据表:我得到 recordsTotal: 1 和 recordsFiltered 0
- javascript - 在加载时切换 Vue3 主题/CSS 文件并单击
- html - 如何显示和隐藏反应 .tsx 文件?