Sohail Saha
Sohail Saha

Reputation: 573

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?

Upvotes: 2

Views: 5099

Answers (3)

Shyam
Shyam

Reputation: 5497

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

Upvotes: 0

e.a.
e.a.

Reputation: 948

in order to access ref in your child component, you need to wrap you component in a React.forwardRef function & use the ref as the second argument & not inside the props object so:

const Child = React.forwardRef((props, ref) => {})

& in your parent you would have:

<Child ref={parentRef}/>

you can read more about it here

Upvotes: 1

Redwan Nassim
Redwan Nassim

Reputation: 407

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

Upvotes: 1

Related Questions