'React: How to get Parent component's width from Child component with hooks?

Say I have 2 components, Parent and Child. I need a way to access Parents's width in Child, and also need useEffect to fire off some code whenever this width changes.

Attempting with useRef gives me an error along the lines of Cannot access clientWidth property of undefined when I use a reference on the parent, and pass it as a prop to child, and try to access it through parentRef.current.clientWidth.

Snippet

const parentRef = useRef();

return(
  <Parent ref={parentRef}>
    <Child parentRef={parentRef}/>
  </Parent>
)

What do I do?



Solution 1:[1]

Make state in parent Make function takes value and change the state Pass function from parent to child in props Execute the function in child with width value

Solution 2:[2]

You can make use of the ResizeObserver api to listen for the resize event attached on your Parent

import { useEffect, useRef, useState } from "react";

const Child = ({ width = 0 }) => {

  useEffect(() => {
    // listen for the change in width
    // do something here when the width changes
  }, [width]);

  return <p> Parent Div Size: {width} </p>;
};

const Parent = () => {
  const divRef = useRef(null);
  const [width, setWidth] = useState(0);

  useEffect(() => {
    const resizeObserver = new ResizeObserver((entries) => {
      // this callback gets executed whenever the size changes
      // when size changes get the width and update the state
      // so that the Child component can access the updated width
      for (let entry of entries) {
        if (entry.contentRect) {
          setWidth(entry.contentRect.width);
        }
      }
    });

    // register the observer for the div
    resizeObserver.observe(divRef.current);

    // unregister the observer
    return () => resizeObserver.unobserve(divRef.current);
  }, []);

  return (
    <div
      ref={divRef}
      style={{
        textAlign: "center",
        height: "100px",
        border: "solid 1px"
      }}
    >
      <Child width={width} />
    </div>
  );
};

export default Parent;

Working Sandbox

Reference

Resize Observer API

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Redwan Nassim
Solution 2