Advertisement
  1. Code
  2. JavaScript
  3. React

Introduction to Animations in React

Scroll to top

When building applications, animations are a great way to improve the overall user experience because they allow for greater interaction between the app and the user.

In some of our previous React tutorials, you got familiar with basic React concepts like JSX, routing, and forms. In this tutorial, we'll take it to the next level and try to understand animations in React. While there are many ways to add animations to a React application, we'll focus on the React Transition Group and how to use it in this article.

Animations in React

React provides a number of add-on utilities for animating React apps, one of which is called the React Transition Group, created by the React developers team.

It's not a library that sets animation styles; rather, it's a low-level API with four types of built-in components: Transition, CSSTransition, SwitchTransition, and TransitionGroup. As a result, animating React components in and out of the DOM during state changes is simple.

The React Transition Group is a very simple tool to get started with, and because it's lightweight, it speeds up the development process by reducing the need for boilerplate code.

Getting Started

First, let's install react using the create-react-app package in our terminal.

1
npx create-react-app react-animations

Open the index.html file of the public folder and edit the title like so:

1
<title>TutsPlus - React Animations</title>

Let's create a folder named components in the src folder of our application and create a Home.js file. Next, we update this file by creating a functional component called Home and rendering an h2 tag.

1
import React from "react";
2
3
const Home = () => {
4
  return (
5
    <>
6
      <h2>{"TutsPlus - Welcome to React Animations!"}</h2>

7
    </>

8
  );
9
};
10
11
export default Home;

Next, update the App.js file by importing the Home component:

1
import React from "react";
2
import Home from "./components/Home";
3
4
const App = () => {
5
  return (
6
    <>
7
      <Home />
8
    </>

9
  );
10
};
11
12
export default App;

Then, start the development server by running:

1
npm run start

React Transition Group Setup

Let's start by trying out a simple animation in React by installing the react-transition-group package to the project.

1
npm install react-transition-group

Next, we import the four components mentioned earlier from the react-transition-group package inside the Home.js file.

1
import {Transition, CSSTransition, SwitchTransition, TransitionGroup} from "react-transition-group";

Next, we'll see how each one of these components works.

The Transition Component

The Transition component provides an API for defining transitions in a component from one state to another during mounting and unmounting.

Now, in the Home component, wrap up the h2 tag inside the Transition component and update the code like so.

1
import React, { useState } from "react";
2
3
const duration = 300;
4
5
const defaultStyle = {
6
  transition: `opacity ${duration}ms ease-in-out`,
7
  opacity: 0,
8
};
9
10
const transitionStyles = {
11
  entering: { opacity: 1 },
12
  entered: { opacity: 1 },
13
  exiting: { opacity: 0 },
14
  exited: { opacity: 0 },
15
};
16
17
const Home = () => {
18
  const [inProp, setInProp] = useState(false);
19
  return (
20
    <>
21
      <div>
22
        <Transition in={inProp} timeout={300}>
23
          {(state) => (
24
            <h2
25
              style={{
26
                ...defaultStyle,
27
                ...transitionStyles[state],
28
              }}
29
            >
30
              {"TutsPlus - Welcome to React Animations"}
31
            </h2>
32
          )}
33
        </Transition>
34
        <button onClick={() => setInProp(!inProp)}>
35
          Click to {inProp ? "Exit" : "Enter"}
36
        </button>
37
      </div>
38
    </>
39
  );
40
};
41
42
export default Home;

Using the Transition tag, we've defined the portion where animation would take place. We also specified an in prop for the transition using inProp state, which toggles the transition state.

As you would have noticed, we specified the animation duration both in the defaultStyle above and in the Transition component using a timeout prop. It's because that's how React knows when to remove the animation classes from the element and when to remove the element from the DOM.

Save the above changes and refresh the page. Once the page has loaded, within a few seconds you should be able to see the animated text.

The CSSTransition Component

When trying to implement a CSS-based animation to your React component, the CSSTransition component comes in handy.

Because this component is based on the Transition component, it inherits all of that component's props and also makes use of a couple of classes to define transitions.

To see how this works, let's add the following code to the index.css file as shown below:

1
.react-animations-enter {
2
  opacity: 0;
3
}
4
.react-animations-enter-active {
5
  opacity: 1;
6
  transition: opacity 200ms;
7
}
8
.react-animations-exit {
9
  opacity: 1;
10
}
11
.react-animations-exit-active {
12
  opacity: 0;
13
  transition: opacity 200ms;
14
}

From *-enter to *-exit-active, each class defines transitions for when components are in the "entering", "entered ", "exiting", and "exited" states.

Then, in Home.js, we'll wrap up our component content into the CSSTransition tag, passing in the in and timeout props as well as the classes we defined earlier:

1
<div>
2
    <CSSTransition
3
        in={displayText}
4
        timeout={300}
5
        classNames="react-animations"
6
        unmountOnExit
7
    >
8
        <h2>{"TutsPlus - Welcome to CSSTransition"}</h2>

9
    </CSSTransition>

10
        <button onClick={() => setDisplayText(!displayText)}>
11
          Display Text
12
        </button>

13
</div>

Notice that the classNames prop above has a react-animations value, which applies to all the classes defined.

The SwitchTransition Class

As the name "switch" suggests, this component is useful when you want to switch rendering between state transitions depending on a selected mode: in-out or out-in mode. It can be useful in scenarios where you want a component to fade out while you insert another.

To access the properties of this utility, we'll also wrap the contents of a component within the SwitchTransition tag. It's also important to note that the SwitchTransition should be used alongside the Transition or CSSTransition components.

Let's add the following code to the index.css file as shown below to create our classes:

1
.fade-enter{
2
   opacity: 0;
3
}
4
5
.fade-exit{
6
   opacity: 1;
7
}
8
9
.fade-enter-active{
10
   opacity: 1;
11
}
12
13
.fade-exit-active{
14
   opacity: 0;
15
}
16
17
.fade-enter-active,
18
.fade-exit-active{
19
   transition: opacity 500ms;
20
}

Let's see how it works, starting with the out-in mode, which is the default mode:

1
 const [state, setState] = useState(false);
2
 
3
   <SwitchTransition>
4
     <CSSTransition
5
       key={state ? "Did you Enjoy our Tutorial?" : "Welcome to TutsPlus"}
6
       addEndListener={(node, done) => node.addEventListener("transitionend", done, false)}
7
       classNames='fade'
8
     >
9
       <button onClick={() => setState(state => !state)}>
10
         {state ? "Did you Enjoy our Tutorial?" : "Welcome to TutsPlus"}
11
       </button>

12
     </CSSTransition>

13
   </SwitchTransition>

The key prop in the code above keeps track of the state in the component, while the addEndListener prop prevents components from flipping almost instantly. Without it, it would appear as if no animation was implemented.

Next is the in-out mode, whereby the SwitchTransition tag takes in a mode prop with a in-out value. Now update your code to see how it works:

1
<SwitchTransition mode={"in-out"}>
2
    {Code goes here}
3
</SwitchTransition>

TransitionGroup

This component helps to manage Transition or CSSTransition components in a list. Below is an example of how it can be applied.

Update Home.js like so:

1
const [items, setItems] = useState(["Manal"]);
2
3
const CONTACTS = ["Jane", "Fred", "John", "Doe", "Brown"];
4
5
const onAddContacts = () => {
6
    const newItem = CONTACTS.find((item) => !items.includes(item));
7
    
8
    if (newItem) {
9
      setItems((prev) => [...prev, newItem]);
10
    }
11
};
12
13
<div>
14
      <TransitionGroup>
15
        <h2>Contacts</h2>

16
        {items.map((item, index) => (
17
          <CSSTransition key={index} timeout={900} classNames="fade">
18
            <p>{item}</p>

19
          </CSSTransition>

20
        ))}
21
        <button onClick={onAddContacts}>Add a Contact</button>

22
      </TransitionGroup>

23
    </div>

Save the above and refresh the page. Click on the button, and the item should be added to the list with animation.

From the code above, we initialized a static set of data called CONTACTS. Then, an onAddContacts function, which will handle adding a new contact, was defined and triggered on the button.

Each item in the list was wrapped in a CSSTransition tag to animate the newly inserted items. Finally, this component was wrapped within the TransitionGroup component to manage the transitions included within it.

Here is the complete Home.js component:

1
import React, { useState } from "react";
2
3
import {
4
  Transition,
5
  CSSTransition,
6
  SwitchTransition,
7
  TransitionGroup
8
} from "react-transition-group";
9
10
const duration = 300;
11
12
const defaultStyle = {
13
  transition: `opacity ${duration}ms ease-in-out`,
14
  opacity: 0,
15
};
16
17
const transitionStyles = {
18
  entering: { opacity: 1 },
19
  entered: { opacity: 1 },
20
  exiting: { opacity: 0 },
21
  exited: { opacity: 0 },
22
};
23
24
const Home = () => {
25
  const [inProp, setInProp] = useState(false);
26
  const [displayText, setDisplayText] = useState(false);
27
  const [state, setState] = useState(false);
28
29
  const [items, setItems] = useState(["Manal"]);
30
31
  const CONTACTS = ["Jane", "Fred", "John", "Doe", "Brown"];
32
33
  const onAddContacts = () => {
34
    const newItem = CONTACTS.find((item) => !items.includes(item));
35
    if (newItem) {
36
      setItems((prev) => [...prev, newItem]);
37
    }
38
  };
39
40
  return (
41
    <>
42
      <div>
43
        <Transition in={inProp} timeout={300}>
44
          {(state) => (
45
            <h2
46
              style={{
47
                ...defaultStyle,
48
                ...transitionStyles[state],
49
              }}
50
            >
51
              {"TutsPlus - Welcome to React Animations"}
52
            </h2>

53
          )}
54
        </Transition>

55
        <button onClick={() => setInProp(!inProp)}>
56
          Click to {inProp ? "Exit" : "Enter"}
57
        </button>

58
      </div>

59
60
      <div>
61
        <CSSTransition
62
          in={displayText}
63
          timeout={300}
64
          classNames="react-animations"
65
          unmountOnExit
66
        >
67
          <h2>{"TutsPlus - Welcome to CSSTransition"}</h2>

68
        </CSSTransition>

69
        <button onClick={() => setDisplayText(!displayText)}>
70
          Display Text
71
        </button>

72
      </div>

73
74
      <div>
75
        <SwitchTransition mode={"in-out"}>
76
          <CSSTransition
77
            key={state ? "Did you Enjoy our Tutorial?" : "Welcome to TutsPlus"}
78
            addEndListener={(node, done) =>
79
              node.addEventListener("transitionend", done, false)
80
            }
81
            classNames="fade"
82
          >
83
            <button onClick={() => setState((state) => !state)}>
84
              {state ? "Did you Enjoy our Tutorial?" : "Welcome to TutsPlus"}
85
            </button>

86
          </CSSTransition>

87
        </SwitchTransition>

88
      </div>

89
90
      <div>
91
      <TransitionGroup>
92
        <h2>Contacts</h2>

93
        {items.map((item, index) => (
94
          <CSSTransition key={index} timeout={900} classNames="fade">
95
            <p>{item}</p>

96
          </CSSTransition>

97
        ))}
98
        <button onClick={onAddContacts}>Add a Contact</button>

99
      </TransitionGroup>

100
    </div>

101
    </>

102
  );
103
};
104
105
export default Home;

Wrapping It Up

In this tutorial, you saw how to get started with using animations in React. You created a simple React app and saw how to implement the four React Transition Group components. For in-depth information on animations in React, I would recommend reading the official documentation.

The source code from this tutorial is available on GitHub.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.