--- id: animation title: Animation Add-Ons permalink: docs/animation.html layout: docs category: Add-Ons redirect_from: - "docs/animation-ja-JP.html" - "docs/animation-ko-KR.html" - "docs/animation-zh-CN.html" --- > Note: > > `ReactTransitionGroup` and `ReactCSSTransitionGroup` have been moved to the [`react-transition-group`](https://github.com/reactjs/react-transition-group/tree/v1-stable) package that is maintained by the community. Its 1.x branch is completely API-compatible with the existing addons. Please file bugs and feature requests in the [new repository](https://github.com/reactjs/react-transition-group/tree/v1-stable). The [`ReactTransitionGroup`](#low-level-api-reacttransitiongroup) add-on component is a low-level API for animation, and [`ReactCSSTransitionGroup`](#high-level-api-reactcsstransitiongroup) is an add-on component for easily implementing basic CSS animations and transitions. ## High-level API: ReactCSSTransitionGroup {#high-level-api-reactcsstransitiongroup} `ReactCSSTransitionGroup` is a high-level API based on [`ReactTransitionGroup`](#low-level-api-reacttransitiongroup) and is an easy way to perform CSS transitions and animations when a React component enters or leaves the DOM. It's inspired by the excellent [ng-animate](https://docs.angularjs.org/api/ngAnimate) library. **Importing** ```javascript import ReactCSSTransitionGroup from 'react-transition-group'; // ES6 var ReactCSSTransitionGroup = require('react-transition-group'); // ES5 with npm ``` ```javascript{31-36} class TodoList extends React.Component { constructor(props) { super(props); this.state = {items: ['hello', 'world', 'click', 'me']}; this.handleAdd = this.handleAdd.bind(this); } handleAdd() { const newItems = this.state.items.concat([ prompt('Enter some text') ]); this.setState({items: newItems}); } handleRemove(i) { let newItems = this.state.items.slice(); newItems.splice(i, 1); this.setState({items: newItems}); } render() { const items = this.state.items.map((item, i) => (
this.handleRemove(i)}> {item}
)); return (
{items}
); } } ``` > Note: > > You must provide [the `key` attribute](/docs/lists-and-keys.html#keys) for all children of `ReactCSSTransitionGroup`, even when only rendering a single item. This is how React will determine which children have entered, left, or stayed. In this component, when a new item is added to `ReactCSSTransitionGroup` it will get the `example-enter` CSS class and the `example-enter-active` CSS class added in the next tick. This is a convention based on the `transitionName` prop. You can use these classes to trigger a CSS animation or transition. For example, try adding this CSS and adding a new list item: ```css .example-enter { opacity: 0.01; } .example-enter.example-enter-active { opacity: 1; transition: opacity 500ms ease-in; } .example-leave { opacity: 1; } .example-leave.example-leave-active { opacity: 0.01; transition: opacity 300ms ease-in; } ``` You'll notice that animation durations need to be specified in both the CSS and the render method; this tells React when to remove the animation classes from the element and -- if it's leaving -- when to remove the element from the DOM. ### Animate Initial Mounting {#animate-initial-mounting} `ReactCSSTransitionGroup` provides the optional prop `transitionAppear`, to add an extra transition phase at the initial mount of the component. There is generally no transition phase at the initial mount as the default value of `transitionAppear` is `false`. The following is an example which passes the prop `transitionAppear` with the value `true`. ```javascript{5-6} render() { return (

Fading at Initial Mount

); } ``` During the initial mount `ReactCSSTransitionGroup` will get the `example-appear` CSS class and the `example-appear-active` CSS class added in the next tick. ```css .example-appear { opacity: 0.01; } .example-appear.example-appear-active { opacity: 1; transition: opacity .5s ease-in; } ``` At the initial mount, all children of the `ReactCSSTransitionGroup` will `appear` but not `enter`. However, all children later added to an existing `ReactCSSTransitionGroup` will `enter` but not `appear`. > Note: > > The prop `transitionAppear` was added to `ReactCSSTransitionGroup` in version `0.13`. To maintain backwards compatibility, the default value is set to `false`. > > However, the default values of `transitionEnter` and `transitionLeave` are `true` so you must specify `transitionEnterTimeout` and `transitionLeaveTimeout` by default. If you don't need either enter or leave animations, pass `transitionEnter={false}` or `transitionLeave={false}`. ### Custom Classes {#custom-classes} It is also possible to use custom class names for each of the steps in your transitions. Instead of passing a string into transitionName you can pass an object containing either the `enter` and `leave` class names, or an object containing the `enter`, `enter-active`, `leave-active`, and `leave` class names. If only the enter and leave classes are provided, the enter-active and leave-active classes will be determined by appending '-active' to the end of the class name. Here are two examples using custom classes: ```javascript // ... {item} {item2} // ... ``` ### Animation Group Must Be Mounted To Work {#animation-group-must-be-mounted-to-work} In order for it to apply transitions to its children, the `ReactCSSTransitionGroup` must already be mounted in the DOM or the prop `transitionAppear` must be set to `true`. The example below would **not** work, because the `ReactCSSTransitionGroup` is being mounted along with the new item, instead of the new item being mounted within it. Compare this to the [Getting Started](#getting-started) section above to see the difference. ```javascript{4,6,13} render() { const items = this.state.items.map((item, i) => (
this.handleRemove(i)}> {item}
)); return (
{items}
); } ``` ### Animating One or Zero Items {#animating-one-or-zero-items} In the example above, we rendered a list of items into `ReactCSSTransitionGroup`. However, the children of `ReactCSSTransitionGroup` can also be one or zero items. This makes it possible to animate a single element entering or leaving. Similarly, you can animate a new element replacing the current element. For example, we can implement a simple image carousel like this: ```javascript{10} import ReactCSSTransitionGroup from 'react-transition-group'; function ImageCarousel(props) { return (
); } ``` ### Disabling Animations {#disabling-animations} You can disable animating `enter` or `leave` animations if you want. For example, sometimes you may want an `enter` animation and no `leave` animation, but `ReactCSSTransitionGroup` waits for an animation to complete before removing your DOM node. You can add `transitionEnter={false}` or `transitionLeave={false}` props to `ReactCSSTransitionGroup` to disable these animations. > Note: > > When using `ReactCSSTransitionGroup`, there's no way for your components to be notified when a transition has ended or to perform any more complex logic around animation. If you want more fine-grained control, you can use the lower-level `ReactTransitionGroup` API which provides the hooks you need to do custom transitions. * * * ## Low-level API: ReactTransitionGroup {#low-level-api-reacttransitiongroup} **Importing** ```javascript import ReactTransitionGroup from 'react-addons-transition-group' // ES6 var ReactTransitionGroup = require('react-addons-transition-group') // ES5 with npm ``` `ReactTransitionGroup` is the basis for animations. When children are declaratively added or removed from it (as in the [example above](#getting-started)), special lifecycle methods are called on them. - [`componentWillAppear()`](#componentwillappear) - [`componentDidAppear()`](#componentdidappear) - [`componentWillEnter()`](#componentwillenter) - [`componentDidEnter()`](#componentdidenter) - [`componentWillLeave()`](#componentwillleave) - [`componentDidLeave()`](#componentdidleave) #### Rendering a Different Component {#rendering-a-different-component} `ReactTransitionGroup` renders as a `span` by default. You can change this behavior by providing a `component` prop. For example, here's how you would render a `