<div id="root"></div>
const { useState, useRef, useCallback, useEffect } = React;

const useResizeObserver = (callback, elements) => {
  useEffect(() => {
    const resizeObserver = new ResizeObserver((entries) => {
      callback(entries);
    });

    for (const elem of elements) {
      elem.current && resizeObserver.observe(elem.current);
    }

    return () => resizeObserver.disconnect();
  }, []);
};

const App = () => {
  const [width, setWidth] = useState(0);

  const element = useRef(null);

  const handleResize = (entries) => {
    const width = entries[0].contentRect.width;
    setWidth(Math.floor(width));
  };

  useResizeObserver(handleResize, [element]);

  const style = {
    backgroundColor: "red",
    height: "40vmin",
    width: "40vmin"
  };

  return (
    <div className="App">
      <div ref={element} style={style}>
        {width}px
      </div>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js