I have a React app where I am hiding/showing an element based on state, and want to do some calculations on that DOM element after the state variable changes.
I've tried using useLayoutEffect, but this still runs before the DOM has updated, so my calculations aren't useful. Is my understanding of useLayoutEffect wrong? Am I using it incorrectly?
Here's what I have
const myComponent = () => {
const elem = useRef()
const [isElemVisible, setIElemVisible] = useState(false)
useLayoutEffect(() => {
// I want this to run AFTER the element is added/removed from the DOM
// Instead this is run before the element is actually modified in the DOM (but the ref itself has changed)
elem.current.getBoundingClientRect() // do something with this object if it exists
}, [elem.current])
return (
<div id="base-element">
{ isElemVisible && (
<div id="element" ref={elem}></div>
)}
</div>
)
}
You can try to pass a function as ref and do stuff in that function:
const myComponent = () => {
// other component code
const elemRef = useCallback((node) => {
if (node !== null) {
// do stuff here
}
}, [])
return (
<div id="base-element">
{ isElemVisible && (
<div id="element" ref={elemRef}></div>
)}
</div>
)
}
Check out this https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node
An easy solution to this, is to manually check for state update in a useEffect hook:
const myComponent = () => {
const elem = useRef()
const [isElemVisible, setIElemVisible] = useState(false)
useEffect(() => {
if (isElemVisible) {
// Assuming UI has updated:
elem.current.getBoundingClientRect() // do something with this object
}
}, [isElemVisible])
return (
<div id="base-element">
{ isElemVisible && (
<div id="element" ref={elem}></div>
)}
</div>
)
}
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