Skip to content Skip to sidebar Skip to footer

How To Get Element Height And Width From Reactnode?

I have a dynamic component in which I pass in children as prop. So the props look something like: interface Props { ...some props children: React.ReactNode } export default

Solution 1:

You can achieve this by using React.Children to dynamically build up a list of references before rendering the children. If you have access to the children element references, you can follow the below approach. If you don't then you can follow the bit at the bottom.

You have access to the children element references

If the children components pass up their element reference, you can use React.Children to loop through each child and get each element reference. Then use this to perform calculations before the children components are rendered.

i.e. This is a very simple example on how to retrieve the references and use them.

interface LayoutWrapperProps {
  onMount: () =>void;
}

constLayoutWrapper: React.FC<LayoutWrapperProps> = ({ onMount, children }) => {
  React.useEffect(() => {
    onMount();
  }, [onMount]);

  return<>{children}</>;
};

constLayout: React.FC = ({ children }) => {
  const references = React.useRef<HTMLElement[]>([]);

  React.useEffect(() => {
    references.current = [];
  });

  functiongetReference(ref: HTMLElement) {
    references.current = references.current.filter(Boolean).concat(ref);
  }

  functiongetHeights() {
    const heights = references.current.map((ref) =>
      ref?.getBoundingClientRect()
    );
    console.log(heights);
  }

  const clonedChildren = React.Children.map(children, (child) => {
    returnReact.cloneElement(child as any, {
      ref: getReference
    });
  });

  return<LayoutWrapperonMount={getHeights}>{clonedChildren}</LayoutWrapper>;
};

If you don't have access to the children element references

If the children components aren't passing up an element as the reference, you'll have to wrap the dynamic children components in a component so we can get an element reference. i.e.

constWrappedComponent = React.forwardRef((props, ref) => {
   return (
     <divref={ref}>
       {props.children}
     </div>
   )
});

When rendering the children components, then the code above that gets the references will work:

<Layout>
  <WrappedComponent><Child1 /></WrappedComponent>
</Layout>

Solution 2:

Since we don't know how your children is built, here is what I can propose you :

importReactfrom'react';
import { render } from'react-dom';

constApp = () => {
  const el1Ref = React.useRef();
  const el2Ref = React.useRef();

  const [childrenValues, setChildrenValues] = React.useState([]);

  React.useEffect(() => {
    setChildrenValues([
      el1Ref.current.getBoundingClientRect(),
      el2Ref.current.getBoundingClientRect()
    ]);
  }, []);
  return (
    <ParentchildrenVals={childrenValues}><spanref={el1Ref}><Childvalue="Hello" /></span><spanref={el2Ref}><Childvalue="<div>Hello<br />World</div>" /></span></Parent>
  );
};

constParent = ({ children, childrenVals }) => {
  React.useEffect(() => {
    console.log('children values from parent = ', childrenVals);
  });
  return<>{children}</>;
};

constChild = ({ value }) => {
  return<divdangerouslySetInnerHTML={{__html:value }} />;
};

render(<App />, document.getElementById('root'));

And here is the repro on Stackblitz.

The idea is to manipulate how your children is built.

Post a Comment for "How To Get Element Height And Width From Reactnode?"