I have one small component, with some text.
In useEffect, I am simply setting the top of the element to some values.
CSS:
.box {
display: flex;
flex-direction: column;
position: relative;
top: 0;
transition: top 0 ease-in;
}
useEffect(() => {
setTimeout(()=> { // with this it is working.
const elems = document.getElementsByClassName("box");
[...elems].forEach(function (e) {
e.style.top =`-200px`; // without settimeout transition is not working
});
});
}, []);
My Markup:
<div className='progress'>
<div className='box' />
<div className='box' />
<div className='box' />
</div>
Now when I do frequent refreshes, I see the transition happening a few times, but not every time.
But when I wrap my code in setTimeout I see a transition every time.
I am not sure why is this happening.
I have no idea about React but what you are trying to do is relatively striaghtforward with @keyframes. There is no need to use setTimeout(). Here is a snippet that you can modify:
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS Animation</title>
<style>
@keyframes moveMeDown {
from {
top: -200px; /* Start position */
}
to {
top: 0; /* End position */
}
}
.box {
display: flex;
flex-direction: column;
position: relative;
top: 0;
animation: moveMeDown 0.7s ease-in; /* Set the name, duration and effect */
}
</style>
</head>
<body>
<section>
<p>Just a test</p>
<div class='progress'>
<div class='box'>One</div>
<div class='box'>Two</div>
<div class='box'>Three</div>
</div>
</section>
</body>
</html>
You just need to change useEffect() to useLayoutEffect(), this is the same as useEffect, but runs after the component Virtual DOM is updated, but before the change is painted to the screen.
This hook is designed to cover the use case in your question.
https://react.dev/reference/react/useLayoutEffect
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