plus1tv / react-anime

✨ (ノ´ヮ´)ノ*:・゚✧ A super easy animation library for React!

Home Page:https://codepen.io/collection/nrkjgo/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Re-runs animation on every render

scarlac opened this issue · comments

Trying to use react-anime for mounting/unmounting of components but animations are re-run every time component is re-rendered, regardless if something changes in child or <Anime ...> definition.

e.g. <Anime opacity={[0, 1]}>hello</Anime> will rapidly flash 'hello' each time you run setState or e.g. props are changed via Redux. This makes the library a bit useless, particularly for Redux, as component must manually be cached and wrapped to avoid this behaviour.

Maybe a feature to limit animations to only run when mounting/unmounting could fix it temporarily.

Version: 2.0.1

Glad to see this issue reported, I just noticed the same thing. I wanted to animate a form into view. Which looks great! Well, until I start typing in the form and it changed the state. I'd love to use this library otherwise!

commented

I'm having the same issue with my form. I was able to get around it by setting the animation duration in state, then changing the duration to 0 in the complete prop. Now the animation appears in the initial render only, but the entire component disappears when my form submit handler fires...

commented

For the moment, I'm using a somewhat hacky workaround to render my form with the <Anime> wrapper on the initial render only, then replace it with the same form without the wrapper once the animation finishes. Its obviously not ideal, but it should serve to make your child component functional until this issue gets addressed.

@echoghni is there any source code you could provide for your workaround? Changing the props of my component the animation is placed in seems to force a re-render

I seemed to stop my animation from "re-looping" by placing my Anime components isolated in their own PureComponent and setting up the shouldComponentUpdate lifecycle event to return false. This prevents my component from ever re-rendering after its' initial mount'

shouldComponentUpdate(nextProps, nextState){
    // Prevent Anime from rerendering animation
    return false;
}

@danieljodeci can you share how you did this? I isolated the component but the animation no longer works.

I have created a workaround that solves the issue for my case of fading an element in only on the first render. If given the chance, I could make this more generic to support all opacity cases, set the ANIMATION_DURATION set to the duration prop value instead, and merge the fix into the library.

export const AnimeWrapper: React.FC = () => {
  const [startOpacity, setStartOpacity] = useState<number>(0)
  useEffect(() => {
    const delayOpacity = setTimeout(() => setStartOpacity(1), ANIMATION_DURATION)
    return () => clearTimeout(delayOpacity)
  }, [])

  return (
      <Anime
        duration={ANIMATION_DURATION}
        opacity={[startOpacity, 1]}
      >
        {children}
      </Anime>
  )
}