maxeth / react-type-animation

A React typewriter animation based on typical with extended functionality and customization.
https://react-type-animation.netlify.app/
MIT License
353 stars 25 forks source link

Callbacks in a sequence is executed even if component is removed before the sequence is finished #59

Closed rangelojc closed 2 weeks ago

rangelojc commented 3 weeks ago

Say we have a long series of text that has a callback after, rendered conditionally.

showMe ? <TypeAnimation
    sequence={[
      someSuperLongText,
      () => console.log("foobar"),
    ]}
  /> : <></>

"foobar" is logged regardless if showMe is suddenly toggled to false between the animation. Is this intended?

Is there a workaround to this?

maxeth commented 2 weeks ago

Hey,

this package was initially just a React wrapper for typical.js, so the logic responsible for the typing animation is a simple, recursive function that modifies the DOM in classic vanilla JS style.

Now, when the component unmounts, the recursive function seems to continue running in the background. I don't think we can do anything against this for now. To properly handle cleanups with component unmounts and allow for dynamic rendering of the component with dynamic props etc., this package would have to be rewritten to the React-way of using useEffect instead of explicit recursion. I'd gladly do this in the near future but I'm highly limited in time.

To address this, the component, for now, is permanently memoized and never meant to be unmounted or re-rendered. So for now, any kind of dynamic usage may be problematic, even though I'm not sure what you're trying to do here.

See https://react-type-animation.netlify.app/#immutability

Hence, I was always sceptical of re-rendering techniques like https://github.com/maxeth/react-type-animation/issues/27 due to the potential memory leaks and unexpected behavior of the recursive functions continuing to run in the background as in your case.


Perhaps you could work with CSS to dynamically hide the animation instead? See: https://react-type-animation.netlify.app/examples#manipulation-via-css-classes

Then within the callback, you could check if the component has the "myActiveClass" class, e.g

 (el) => { if(el.classList.contains("myActiveClass")) console.log("foobar") }

And to hide the animation, you could delete "myActiveClass" from the component via useRef as shown in the example https://react-type-animation.netlify.app/examples#manipulation-via-css-classes under "useRef Hook" tab.

rangelojc commented 2 weeks ago

Sounds good. It's a minor issue overall. TY for the response.

Decent workaround! Closing this for now.