I have the following component:
// component.js
import React from 'react';
import useComponentSize from 'useComponentSize';
const component = () => {
const [comSize, comRef] = useComponentSize();
return (
<div style={{width: '100%'}} ref={comRef}>
<p>hi</p>
</div>
);
};
which is using useComponentSize, a hook I've made:
// useComponentSize.js
import {
useRef,
useState,
useLayoutEffect,
} from 'react';
const useComponentSize = () => {
const [size, setSize] = useState({
width: 0,
height: 0,
});
const resizeRef = useRef();
useLayoutEffect(() => {
setSize(() => ({
width: resizeRef.current.clientWidth,
height: resizeRef.current.clientHeight,
}));
});
return [size, resizeRef];
};
export default useComponentSize;
but for a reason I cannot work out, it always exceeds the maximum update depth. I've tried having useLayoutEffect depend upon resizeRef, which I thought would work, but then it doesn't update again (which upon reflection is exactly how I should have expected a ref to work).
What should I do to make this work properly, and most importantly why does the above cause an infinite loop?
Edit: second attempt using event listeners, still failing. What concept am I missing here?
// component.js
import React, { useRef } from 'react';
import useComponentSize from 'useComponentSize';
const component = () => {
const ref = useRef();
const [comSize] = useComponentSize(ref);
return (
<div style={{width: '100%'}} ref={ref}>
<p>hi</p>
</div>
);
};
import {
useRef,
useState,
useLayoutEffect,
} from 'react';
const useComponentSize = (ref) => {
const [size, setSize] = useState();
useLayoutEffect(() => {
const updateSize = () => {
setSize(ref.current.clientWidth);
}
ref.current.addEventListener('resize', updateSize);
updateSize();
return () => window.removeEventListener('resize', updateSize);
}, []);
return [size];
};
export default useComponentSize;
That edit above is based upon this useWindowSize hook, which works great (I'm using it currently as a replacement, although I'd rather still get the above to work, and especially to know why it doesn't work).
A small explanation of what I'm trying to achieve as it wasn't made explicitly clear before: I want the state size to update whenever the size of the referenced component's size changes. That is, if the window resizes, and the component remains the same size, it should not update. But if the component size does change, then the size state should change value to reflect that.