Observing Next Images loaded asynchronously with ResizeObserver API
Answered
Californian posted this in #help-forum
CalifornianOP
I'm using ResizeObserver API to observe, inside an useEffect hook, a bunch of references to Next Image elements which are loaded asynchronously into component states in another useEffect hook.
- Problem: if I observe before the images are loaded into the states, the observer callback can't recognize the references.
- Work Around: observe only after a few miliseconds.
Is there a better solution ?
- Problem: if I observe before the images are loaded into the states, the observer callback can't recognize the references.
- Work Around: observe only after a few miliseconds.
Is there a better solution ?
Answered by Ray
useEffect(() => {
if (!imageState) return;
const resizeObserver = new ResizeObserver(() => {
// Do what you want to do when the size of the element changes
});
resizeObserver.observe(ref.current);
return () => resizeObserver.disconnect();
}, [imageState]);
6 Replies
try this?
const ref = useRef<HTMLImageElement>(null);
useEffect(() => {
if (!ref.current?.complete) return;
const resizeObserver = new ResizeObserver(() => {
// Do what you want to do when the size of the element changes
});
resizeObserver.observe(ref.current);
return () => resizeObserver.disconnect();
}, []);
return (
<>
<Image ref={ref} src="" alt="" />
</>
)
CalifornianOP
This was what I first did, but actually in my case the Image is loaded asynchronously by another function, inside another useEffect hook. So, the observer can't observe it at this moment. My work around is something like:
I'm wondering if there is something better than this imprecise
const ref = useRef<HTMLImageElement>(null);
const [imageState, setImageState] = useState<ImageInterface>(null);
useEffect(() => {
const imageData = await imageLoader(...);
setImageState(imageDate);
}, []);
useEffect(() => {
if (!ref.current?.complete) return;
const resizeObserver = new ResizeObserver(() => {
// Do what you want to do when the size of the element changes
});
setTimeout(() => {resizeObserver.observe(ref.current);}, 200);
return () => resizeObserver.disconnect();
}, []);
return (
<>
<Image ref={ref} src=imageState.src width=imageState.width height=imageState.height alt="" />
</>
)
I'm wondering if there is something better than this imprecise
setTimeout
strategy.if (!imageState) return
how about this?
setTimeout is not a good solution for slow network speed lol
useEffect(() => {
if (!imageState) return;
const resizeObserver = new ResizeObserver(() => {
// Do what you want to do when the size of the element changes
});
resizeObserver.observe(ref.current);
return () => resizeObserver.disconnect();
}, [imageState]);
Answer
CalifornianOP
Ah, good idea that of binding the imageState to the useEffect hook. Thanks, this works !