Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update UI when useRef Div Width Changes

Tags:

reactjs

I have a useRef attached to a div. I need to update my UI when the div's width changes. I can access this using ref.current.innerWidth, however, when its width changes, it doesn't update other elements that depend on ref.current.innerWidth.

How can I do this?

CODE:

let ref = useRef();

return (
  <>
    <Box resizable ref={ref}>
      This is a resizable div
    </Box>

    <Box width={ref.current.innerWidth}>
      This box needs the same with as the resizable div
    </Box>
  </>
);

2 Answers

You could use a ResizeObserver. Implemented like so, it will set the width everytime the size of the ref changes:

let ref = useRef()

const [width, setwidth] = useState(0)

useEffect(() => {
  const observer = new ResizeObserver(entries => {
    setwidth(entries[0].contentRect.width)
  })
  observer.observe(ref.current)
  return () => ref.current && observer.unobserve(ref.current)
}, [])

return (
  <>
    <Box ref={ref}>
      This is a resizable div
    </Box>

    <Box width={width}>
      This box needs the same with as the resizable div
    </Box>
  </>
)

like image 149
fredy Avatar answered Mar 26 '26 10:03

fredy


For anyone looking for a reusable logic and a Typescript support, I created the below custom hook based on @fredy's awesome answer, and also fixed some issues I've found in his answer:

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


export const useObserveElementWidth = <T extends HTMLElement>() => {
    const [width, setWidth] = useState(0);
    const ref = useRef<T>(null);

    useEffect(() => {
        const observer = new ResizeObserver((entries) => {
            setWidth(entries[0].contentRect.width);
        });

        if (ref.current) {
            observer.observe(ref.current);
        }

        return () => {
            ref.current && observer.unobserve(ref.current);
        };
    }, []);

    return {
        width,
        ref
    };
};

Then, import useObserveElementWidth, and use it like this:

const YourComponent = () => {
  const { width, ref } = useObserveElementWidth<HTMLDivElement>();

  return (
    <>
      <Box resizable ref={ref}>
        This is a resizable div
      </Box>

      <Box width={width}>
        This box needs the same with as the resizable div
      </Box>
    </>
  );
};

I've created an example codesandbox for it.

like image 41
Elyasaf755 Avatar answered Mar 26 '26 09:03

Elyasaf755