Navigate back to the homepage
BLOG
Try NowLogin
Back

How to use React Transition Group & React Animation Library

Paige Niedringhaus
September 16th, 2020 · 9 min read

A few months ago, I gave a talk with a coworker at the tech conference Connect.Tech about the ever-growing need for responsive web design when building websites and applications. During the presentation, we discussed a few different ways to approach it, specifically when it comes to the JavaScript framework React.

While I won’t go into all the details in our talk of how to approach responsive design (if you’d like, you can see the full slide deck of the talk here), I did want to share a handy React animation library I stumbled across while building the mobile-responsive demo application, called React Transition Group.


React Transition Group

What makes it different?

Unlike other React animation libraries like React Spring or React Reveal, React Transition Group “exposes simple components useful for defining entering and exiting transitions…it does not animate styles by itself. Instead it exposes transition stages, manages classes and group elements and manipulates the DOM in useful ways, making the implementation of actual visual transitions much easier.”

React Transition Group is a lower-level type of animation library. It doesn’t care nearly as much about what type of animation you’d like to do, it just makes it easier to do any sort of animation on any React component with as little hassle as it can.

And it doesn’t hurt to know that React Transition Group began in the original React framework (it’s mentioned in the docs) before being spun out into a new package to be maintained by the community. That’s a pretty good endorsement for trying RTG, in my book.

Now that you know a little more about RTG’s approach to animation, let me cover a few of the different component options it gives users, and how they work.

Types of RTG Components

React Transition Group offers four different types of components for users to choose from based on their animation needs.

Transition

The first component to cover is Transition. This component lets you describe a transition from one component state to another over a span of time with a simple API. Most commonly it’s used to animate the mounting and unmounting of a component, but it can also be used to describe in-place transition states as well. Personally, I tend to favor CSSTransition over the straight Transition component, but that’s just me.

The transition component tracks the “enter” and “exit” states for the component. The four main states a Transition can be in are:

  • 'entering'
  • 'entered'
  • 'exiting'
  • 'exited'

The transition state is toggled on via the in prop, when it’s true the component will begin the entering stage for the duration of the transition until it’s fully visible, at which point it will switch to the entered stage. Upon exit, the same things will happen with exiting and exited.

A simple example of fading in a component on enter and fading it out on exit might look something like this:

text

This illustrates using React Transition Group’s Transition component to fade a component into view for the user.

In the example above, once the inProp prop is true, the Transition component will activate and begin fading in to view courtesy of the transitionStyles variable (where opacity is defined) that correspond to the various “enter” or “exit” stages I outlined earlier.

It’s worth noting this is a platform-agnostic base component — if you’re looking for CSS transitions (like I was for my use case), you’ll probably want the CSSTransition component instead.

CSSTransition

If you’re using CSS transitions or animations, the CSSTransition component is what you’ll want to use; it’s built upon the Transition component, so it inherits all of its props.

To work, CSSTransition applies a pair of class names during the appear, enter, and exit states of the transition. The first class is applied and then a second *-active class in order to activate the CSS transition. After the transition, matching *-done class names are applied to persist the transition state.

For instance, if your CSSTransition component’s classNames property is sample, you’d first see sample-enter, then sample-enter-active, and finally sample-enter-done for the ending state when the animation is done. And when it’s time to reverse the animation (such as with a modal or slider that needs to disappear or exit the screen), you’d see it cycle through sample-exit and sample-exit-active and sample-exit-done on your component’s classNames property.

Here’s a simplified code sample of what the JSX and accompanying CSS classes might looks like for making a div of text fade in or out. (I’ve omitted the imports at the top of the file because they’re the same named import for each type of component from RTG: import { CSSTransition } from 'react-transition-group';.)

First the JavaScript code showing the CSSTransition component wrapping a div element to show or hide based on the state of isVisible, which is toggled by the button element underneath.

text

Here’s the JavaScript JSX code where the CSSTransition component is used to wrap the div and text to show or hide.

And here’s the CSS classes that the CSSTransition component would experience once isVisible became true and triggered the in prop to fade the text in or out (just like with the original Transition component).

text The CSS transition states that will actually cause the text wrapped in the CSSTransition to component to fade in and out of view.

*-active classes represent which styles you want to animate to, so it’s important to add the transition declaration only to them, otherwise transitions might not behave as intended. This might not be obvious when the transitions are symmetrical, i.e. when *-enter-active is the same as *-exit, but it becomes apparent quickly in more complex transitions.

Let’s move on now to React Transition Group’s next option: SwitchTransition.

SwitchTransition

This component is useful if you want to control the render between state transitions, it’s inspired by Vue transition modes. Based on the selected mode (in-out or out-in), and the child’s key which is the Transition or CSSTransition component, the SwitchTransition makes a consistent transition between them.

If out-in mode is selected, SwitchTransition waits until the old child leaves and then inserts a new child. If the in-out mode is selected, the SwitchTransition inserts a new child first, waits for the new child to enter and then removes the old child.

Here’s an example so you can see how the code might be structured to make two different buttons “switch” places in the DOM based on the current state. Once again, imports at the top of the file omitted for brevity.

text

The Button element gets replaced each time it’s clicked with a new button featuring the opposite text of what the previous button text was, courtesy of SwitchTransition.

Here, SwitchTransition wraps the CSSTransition component, which actually handles the logic and animating of entering a new Button and exiting the existing one. The key in CSSTransition keeps track of state in the component, and every time the state changes (based on a button click), the CSSTransition component takes action and SwitchTransition handles the keeping the old button visible until after the new button has appeared, which CSSTransition is fading out based on its event listener.

That addEndListener function is crucial to animating the switch between elements, without it, the state (and components) will instantaneously flip like there’s no animations at all.

Here’s the CSS for the fade class name associated with CSSTransition.

text

This CSS is really for the animated entrances and exits of the buttons in the DOM, but I wanted to show it anyway.

The CSS here is really concerned with the CSSTransition component wrapped inside of SwitchTransition, but I figure the more sample code you see for how to animate things in and out of the DOM, the better.

It takes some trial and error to get it right, but the documentation for SwitchTransition is good and I’m sure you’ll figure it out without much of a problem if this is the kind of animation you desire in your application.

TransitionGroup

Last but not least is the { <TransitionGroup> component. This component manages a set of transition components (<Transition> and <CSSTransition>) in a list. Like with the individual transition components, <TransitionGroup> is a state machine for managing the mounting and unmounting of components over time.

Please note that <TransitionGroup> does not define any animation behavior. Exactly how a list item animates is up to the individual transition component, which means you can mix and match animations across different list items, which could be handy.

Unlike SwitchTransition which lets you control the entering and exiting of elements in the DOM, TransitionGroup will make the animations happen simultaneously (i.e., to remove the old child and insert a new child at the same time).

Take a look at this example of a simple chore list that can have chores removed from it once they’re completed. First, the JSX code with no imports in the example.

text

TransitionGroup wraps the list of CSSTransition components which will be removed from the list as they’re completed.

And, here’s the CSS that will make the chores fade out of the DOM as they’re removed.

text

Once more, the CSS belongs to the CSSTransition components so they can enter and leave the DOM in an animated fashion.

And with that, I’ve covered all the main component options React Transition Group offers. All in all, using one or more of these components together gives you fine grained control over what type of and how your React components animate in the DOM. Now, let’s get down to the business of how exactly I used React Transition Group to animate my mobile navbar in my demo site.


How I used RTG in My React App

The use case I had for React Transition Group is a fairly standard one, I’m sure. For my app, a movie demo site I built using the Movie Database API for a data source, when it was in mobile view, I wanted the navbar (normally across the top of the page in larger layouts) to condense down to the well-recognized hamburger menu, and require users to click it to open the list of links.

What I needed was to animate a mobile-sized navbar to slide into and out of the DOM for the user, at the touch of a button. Seemed like a simple enough request.

Here’s a video of what I envisioned happening.

Easy enough, right? Slide a navbar in when the user clicks the hamburger icon. slide it back out when they click the icon again.

The code I’ll be showing you are actual snippets taken from the demo site you’re seeing in the video above. If you’d like to see the whole codebase for this project, it’s available on GitHub, and if you’d like to see a live version of the site, it’s available on this website (just make your desktop browser mobile-sized to see the animated navbar).

Step 1: Add CSSTransition Group to the Sidebar.js Component

The first thing I had to do after installing React Transition Group into my project’s dependencies with npm -i react-transition-group, was add it to the component I wanted to animate.

This component is named Sidebar and its full JavaScript code looks like this.

Sidebar.js

text

This is the entire Sidebar component. The code before the CSSTransition component is just the hamburger icon and click function to toggle CSSTransition into action.

I’ll quickly break down what goes into this component. The way that Sidebar triggers the in prop in the CSSTransition component (which will reveal all the navigation links to other pages in the site housed within the sidebar) is with the toggleLinks function.

Once toggleLinks changes the expandedLinks state to true, the CSSTransition component runs and adds the class name modifiers ( enter, enter-active, exit, etc.) to the visible class present on the CSSTransition component.

And all I had to do to hide the sidebar links until I’m ready for them, was wrap the main div surrounding all the links with the CSSTransition component. Pretty straightforward, so far, right?

Step 2: Generate the CSS to Support RTG’s Animation Class Names

Now for the CSS. It’s long, I’ll admit — I did a lot of styling to make this navbar look just how I wanted, but try to bear with me. It’s really not complicated, just verbose from styling (and this is a condensed version where I cut out some extraneous CSS not relevant to this article).

Sidebar.scss

text

Yes, it’s a lot of CSS, but the finished product is worth it in my mind.

If you wade through all this styling and focus on the transform and translate properties in each class I’ve defined above, you’ll see what is causing the animation I want. I slide the navbar in to view on .visible-enter-active with transition: transform 0.3s linear; and slide it back out of view with .visible-exit-active and transition: transform 0.3s linear;. Piece of cake!


Conclusion

Responsive web design is only gaining more importance as technology touches more and more of our daily lives, and smooth animations to make that technology feel more natural are essential.

React Transition Group makes animations of all kinds easy by providing 4 basic components and an easy-to-use API unconcerned with the specific types of animation it’s enabling. This low-level implementation gives developers fine-grain control over exactly how their app’s components flow in the DOM for the best user experience they can provide. RTG is really easy to get up and running, and a pleasure to develop with.

Check back in a few weeks — I’ll be writing more about JavaScript, React, ES6, or something else related to web development.

Thanks for reading. If you’re looking to add some slick animations to your React app, I hope you’ll consider React Transition Group among the myriad of libraries out there. It makes animations simple and straightforward, even down to the tiny, micro-animation details. Give it a shot — you won’t regret it.

Read the original article or more interesting posts on Paige’s blog.

If you enjoyed reading this, you may also enjoy some of my other free pieces:


References and Further Resources

More articles from Asayer Blog

Find Your Best Code Solution Understanding Big 0 Notation

Big 0 is a concept that describes the runtime and space complexity of your solution in terms of how quickly it grows relative to the input.

September 7th, 2020 · 4 min read

Steps to Develop Global State for React With Hooks Without Context

Learn how to use state and other React features without writing a class.

August 31st, 2020 · 2 min read
© 2020 Asayer Blog
Link to $https://twitter.com/asayerioLink to $https://github.com/asayerioLink to $https://www.linkedin.com/company/18257552