Search code examples
reactjsnext.jsmapboxmapbox-gl-jsuse-ref

Use ref with and height


I was wondering how to get useRef width and height on load and when it changes.

I am trying to pass the exact dimensions of a component to its child.

MapContainer.js

const mapComponent = useRef(null);
const [mapWidth, setMapWidth] = useState(0);
const [mapHeight, setMapHeight] = useState(0);

useEffect(() => {
    if (mapComponent.current !== null) {
      setMapWidth(mapComponent.current.clientWidth);
      setMapHeight(mapComponent.current.clientHeight);
    }
  }, [mapComponent]);

<div className={`bg-white rounded-[32px] overflow-hidden relative`} ref={mapComponent}>
   <Map
     style="mapbox://styles/ayagoumi/ckyvm0dx5001714mplg2y1oz7"
     zoom={zoom}
     center={position}
     movingMethod="easeTo"
     containerStyle={{
       height: `${mapHeight}px`, // this is what i want to change
       width: `${mapWidth}px`, // this is what i want to change
       borderRadius: "32px",
       zIndex: "0",
       overflow: "hidden",
     }}
   >
   </Map>
</div>

Index.js

<section className="flex flex-wrap justify-between w-full gap-4 xl:flex-nowrap">
     <div></div>
     <div className="flex flex-col order-2 gap-4 sm:flex-row grow">
       <MapContainer styles="w-full md:!w-[50%] lg:w-full min-w-[300px] min-h-[300px] order-2 rounded-[32px] overflow-hidden"></MapContainer>
     </div>
</section>

But this approach that I took is not getting me the width and height when parent width changes


Solution

  • To get the new width and height after resizing, you need to listen to resize event of window, as example:

    const Map = () => {
      const mapComponent = useRef(null);
      const [mapWidth, setMapWidth] = useState(0);
      const [mapHeight, setMapHeight] = useState(0);
      
      const onResize = () => {
        const rect = mapComponent.current.getBoundingClientRect();
        if (rect) {
          setMapWidth(rect.width);
          setMapHeight(rect.height);
        }
      };
    
      useEffect(() => {
        onResize();
        window.addEventListener('resize', onResize);
      }, []);
    
      return (
        <div ref={mapComponent}>
          <Child width={mapWidth} height={mapHeight}>A</Child>
          <Child width={mapWidth} height={mapHeight}>B</Child>
          <Child width={mapWidth} height={mapHeight}>C</Child>
          <Child width={mapWidth} height={mapHeight}>D</Child>
        </div>
      );
    };