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