react-hook
react-hook copied to clipboard
Reference change doesn't reflect in the entry
Describe the bug When the chartRef changes. The entry still points to the original reference rather than being updated.
Sorry, can you elaborate?
Given the example:
import * as React from 'react'
import useResizeObserver from '@react-hook/resize-observer'
const useSize = (target) => {
const [size, setSize] = React.useState()
React.useLayoutEffect(() => {
setSize(target.current.getBoundingClientRect())
}, [target])
// Where the magic happens
useResizeObserver(target, (entry) => setSize(entry.contentRect))
return size
}
const App = () => {
const target = React.useRef(null)
const size = useSize(target)
const [useOther, setUseOther] = useState(false);
return (
<div>
{ !useOther &&
<div id="1" ref={target}>
{JSON.stringify({width: size.width, height: size.height}, null, 2)}
</div>
}
{ useOther &&
<div id="2" ref={target}>
{JSON.stringify({width: size.width, height: size.height}, null, 2)}
</div>
<button onClick={() => setUseOther(!useOther)} />
}
</div>
)
}
useResizeObserver will observe changes to 'id 1' but when the button is clicked and the reference changes to 'id 2', the target.current will change its reference, but that change is not reflected in the useResizeObserver. It still reflects changes on 'id 1'.
Would advise against doing what you're doing. Use a separate ref and useSize hook for each div instead
Even when using a separate ref and useSize hook the newly rendered ref's useSize only seems to return 0, 0. Has anyone has success with this swap technique?
I believe this issue has bit me too; my use case is simpler than that previously presented here, and I think it should be supported (currently it isn't supported). My component looks like this:
function App() {
const [loading, setLoading] = useState(true);
const target = useRef(null);
const [width, height] = useSize(target);
useEffect() {
// call async function and eventually setLoading(false);
}, []);
return loading ? <></> : <div ref={target}/>;
}
So, the ref is not assigned on the first render because the respective div does not exist yet.
cc @laurolins