Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transition not working without setTimeout in useEffect

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.

like image 921
Rahul Avatar asked Jul 21 '26 22:07

Rahul


2 Answers

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>
like image 134
jQueeny Avatar answered Jul 24 '26 12:07

jQueeny


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

like image 37
David Bradshaw Avatar answered Jul 24 '26 11:07

David Bradshaw



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!