[英]How to get element height and width from 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
的頁面是動態生成的。
您可以通過使用React.Children
在渲染子項之前動態構建引用列表來實現這一點。 如果您有權訪問子元素引用,則可以遵循以下方法。 如果你不這樣做,那么你可以按照底部的位。
如果子組件傳遞了它們的元素引用,您可以使用React.Children
循環遍歷每個子組件並獲取每個元素引用。 然后在渲染子組件之前使用它來執行計算。
即這是一個關於如何檢索引用並使用它們的非常簡單的示例。 如果添加/刪除了多個組件,因為它將它存儲在一個集合中並且不刪除組件,這將不會是高性能的。
const Layout = ({ children }) => {
const references = useRef(new Set());
function getReference(ref) {
references.current.add(ref);
}
const clonedChildren = React.Children.map(children, (child) => {
return React.cloneElement(child, {
ref: getReference
});
});
const heights = React.useMemo(() => {
return Array.from(references.current).map((ref) => ref.getBoundingClientRect());
}, [references.current]);
return clonedChildren;
}
如果子組件沒有傳遞元素作為引用,則必須將動態子組件包裝在一個組件中,以便我們可以獲得元素引用。 IE
const WrappedComponent = React.forwardRef((props, ref) => {
return (
<div ref={ref}>
{props.children}
</div>
)
});
渲染子組件時,上面獲取引用的代碼將起作用:
<Layout>
<WrappedComponent>
<Child1 />
</WrappedComponent>
</Layout>
由於我們不知道您的children
是如何構建的,因此我可以向您提出以下建議:
import React from 'react';
import { render } from 'react-dom';
const App = () => {
const el1Ref = React.useRef();
const el2Ref = React.useRef();
const [childrenValues, setChildrenValues] = React.useState([]);
React.useEffect(() => {
setChildrenValues([
el1Ref.current.getBoundingClientRect(),
el2Ref.current.getBoundingClientRect()
]);
}, []);
return (
<Parent childrenVals={childrenValues}>
<span ref={el1Ref}>
<Child value="Hello" />
</span>
<span ref={el2Ref}>
<Child value="<div>Hello<br />World</div>" />
</span>
</Parent>
);
};
const Parent = ({ children, childrenVals }) => {
React.useEffect(() => {
console.log('children values from parent = ', childrenVals);
});
return <>{children}</>;
};
const Child = ({ value }) => {
return <div dangerouslySetInnerHTML={{ __html: value }} />;
};
render(<App />, document.getElementById('root'));
這是Stackblitz 上的重現。
這個想法是操縱你的孩子是如何建造的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.