Animations with ReactTransitionGroup

When and how to use ReactTransitionGroup

While nearly any animation can be done in CSS, they tend to be more difficult to maintain once they reach a certain level of complexity.

ReactTransitionGroup is the API upon which ReactCSSTransitionGroup is built. The main difference between the two is that ReactTransitionGroup animations are written in Javascript instead of CSS, and a callback is provided to be invoked when animations are complete instead of relying on CSS transition events.

Starting off simple

Let’s start with a page that has a div that’s conditionally shown based on the flag shouldShowBox, we’ll leave transition groups out for now.

When shouldShowBox is true, the “.box” is visible, and when it’s false, it’s not.

Adding ReactTransitionGroup

Install react-addons-transition-group

npm install react-addons-transition-group

Then import to our file via

import TransitionGroup from 'react-addons-transition-group';

Now, add the TransitionGroup to our `Page` component’s render so that it becomes:

To give components inside the TransitionGroup the flexibility of having differing animations, the TransitionGroup does not define animations itself, but will call the corresponding enter or leave animation hooks on its child components when the child components are added or removed.

You will typically only need these two lifecycle hooks -

  • componentWillEnter(callback)
    Called on components that are added to an existing TransitionGroup, at the same time as the component’s componentDidMount.
    Not called on the initial render of the entire TransitionGroup (e.g. when a page is initially loaded), for that you’d want componentWillAppear
  • componentWillLeave(callback)
    Called on components that have been removed from a TransitionGroup. This is called before componentWillUnmount, and componentWillUnmount will not trigger until the callback here is called.

Note that you must call the supplied callbacks after your animation ends, otherwise your component will enter but not leave, or leave but not enter.

See the official docs for detailed info on all the animation lifecycle hooks.

Because ReactTransitionGroup relies on those hooks to exist, and a div doesn’t have those hooks defined, we’ll have to first move our <div className=”box”/> into its own component:

Then add in the animation lifecycle hooks. We’ll be using GSAP’s TweenMax for animation.

Update Jan 23rd 2017: Now using refs for referencing the DOM element. For more on refs, see documentation on Refs and the DOM

For those unfamiliar with TweenMax, here’s the function signature of fromTo:

TweenMax.fromTo( target:Object, duration:Number, fromVars:Object, toVars:Object ):TweenMax

Now we have a simple animation using ReactTransitionGroup!

The next few parts will be on reusing animations via higher-order components, integrating with react-router, and coordinating nested transitions.

If you’ve read this far then you might also like “Quick and dirty tricks for debugging Javascript 🕵”, and tweet at me @CheapSteak :)

You may also be interested in react-transition-group-plus, a drop-in replacement for ReactTransitionGroup that allows interruptible transitions and specifying transition order. See a comparative demo here.

Thanks to @hare_ben and @jephuff for proofreading and feedback