React animation example and how it works
This is a step-by-step tutorial to make a React animation that looks like this:
But before we start let’s clear up the biggest source of confusion when it comes to animations in React.
When do I need the add-on ReactCSSTransitionGroup to do a React animation?
If you look in the animation section in the React docs. You learn there is an add-on called ReactCSSTransitionGroup.
But why do you need an add-on to do a React animation? Why can’t you specify keyframes/animations in CSS?
The answer is that there is one case when you need this add-on. And that is when you want to animate a component being inserted or removed from the DOM.
All other types of animation can be coded in regular CSS.
Examples of when you don’t need ReactCSSTransitionGroup and you can use pure CSS:
- a loading animation spinner
- hover effect
Examples of when you need to use ReactCSSTransitionGroup:
- Animating a Route change
- Animating the steps in a multi-step form
The React animation example using ReactCSSTransitionGroup
Now let’s implement the React animation.
When clicking no, the second box disappears. Because we want to animate an element disappearing from the DOM, we need to use the add-on ReactCSSTransitionGroup
.
The JSX
Let’s start by writing the React components. I only show the JSX to keep it short and readable, for full code scroll to the bottom of this post.
<div>
<div className="step">
<h2>Do you like cats?</h2>
<div>
<input type="radio" name="cats" checked={this.state.likeCats} onChange={this.toggleLikeCats}/> Yes
</div>
<div>
<input type="radio" name="cats" checked={!this.state.likeCats} onChange={this.toggleLikeCats}/> No
</div>
</div>
{this.state.likeCats ?
<div className="step">
<h2>What kind do you like?</h2>
<input type="text" />
</div>
: null}
</div>
Note that the two sections of the form are implemented as two divs. They are both using the CSS className step
.
Adding ReactCSSTransitionGroup
In the latest version of React, ReactCSSTransitionGroup
has been moved to its own repository and there have been some changes in the API. We will use this latest version which is v2.
To be able to animate when a component enters and leaves the DOM we are going to use add-on TransitionGroup
and CSSTransition
components.
We will wrap both of our step-divs with the TransitionGroup
component. And we will wrap each div with one CSSTransition component. It looks like this:
<div>
<TransitionGroup>
<CSSTransition timeout={100} classNames="step">
<div className="step">
<h2>Do you like cats?</h2>
<div>
<input type="radio" name="cats" checked={this.state.likeCats} onChange={this.toggleLikeCats}/> Yes
</div>
<div>
<input type="radio" name="cats" checked={!this.state.likeCats} onChange={this.toggleLikeCats}/> No
</div>
</div>
{this.state.likeCats ?
<CSSTransition timeout={100} classNames="step">
<div className="step">
<h2>What kind do you like?</h2>
<input type="text" /> </div> : null}
</TransitionGroup>
</div>
When a user clicks yes, and second step component enters the DOM, it adds the CSS class step-enter
to the component that enters, and when it leaves it adds the class name step-leaves
. There is also an “active” class that activates the animation. We are going to style these classes with CSS to create the actual animation in the next step.
CSSTransition
takes a prop timeout that means for how long the class should be on the components
Our CSS animation
Last but not least we are going to add our CSS animation. We are animating the classes added by TranstionGroup
.step-enter {
opacity: 0;
transform: translate(-500px, 0);
transform: translate3d(-500px, 0, 0);
}
.step-enter.step-enter-active {
opacity: 1;
transition: opacity 2s ease;
transform: translate(0,0);
transform: translate3d(0,0,0);
transition-property: transform, opacity;
transition-duration: 100ms;
transition-timing-function: cubic-bezier(0.175, 0.665, 0.320, 1), linear;
}
.step-exit {
opacity: 1;
transform: translate(0, 0, 0);
transform: translate3d(0, 0, 0);
transition-property: transform, opacity;
transition-duration: 100ms;
transition-timing-function: cubic-bezier(0.175, 0.665, 0.320, 1), linear;
}
.step-exit.step-exit-active {
opacity: 0;
transform: translate(500px, 0);
transform: translate3d(500px, 0, 0);
}
Try coding the React animation yourself!
Now try to implement your own React animation. Get the full code from the tutorial by signing up below!