簡體   English   中英

如何從 ReactNode 獲取元素的高度和寬度?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM