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>
</>
);
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>
</>
)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With