--- id: animation title: Animation permalink: animation.html prev: addons.html next: two-way-binding-helpers.html --- React provides a `ReactTransitionGroup` addon component as a low-level API for animation, and a `ReactCSSTransitionGroup` for easily implementing basic CSS animations and transitions. ## High-level API: `ReactCSSTransitionGroup` `ReactCSSTransitionGroup` is based on `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](http://www.nganimate.org/) library. ### Getting Started `ReactCSSTransitionGroup` is the interface to `ReactTransitions`. This is a simple element that wraps all of the components you are interested in animating. Here's an example where we fade list items in and out. ```javascript{28-30} var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup; var TodoList = React.createClass({ getInitialState: function() { return {items: ['hello', 'world', 'click', 'me']}; }, handleAdd: function() { var newItems = this.state.items.concat([prompt('Enter some text')]); this.setState({items: newItems}); }, handleRemove: function(i) { var newItems = this.state.items; newItems.splice(i, 1); this.setState({items: newItems}); }, render: function() { var items = this.state.items.map(function(item, i) { return (
{item}
); }.bind(this)); return (
{items}
); } }); ``` > Note: > > You must provide [the `key` attribute](/react/docs/multiple-components.html#dynamic-children) for all children of `ReactCSSTransitionGroup`, even if 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; transition: opacity .5s ease-in; } .example-enter.example-enter-active { opacity: 1; } ``` You'll notice that when you try to remove an item `ReactCSSTransitionGroup` keeps it in the DOM. If you're using an unminified build of React with add-ons you'll see a warning that React was expecting an animation or transition to occur. That's because `ReactCSSTransitionGroup` keeps your DOM elements on the page until the animation completes. Try adding this CSS: ```css .example-leave { opacity: 1; transition: opacity .5s ease-in; } .example-leave.example-leave-active { opacity: 0.01; } ``` ### 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. 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{12-15} render: function() { var items = this.state.items.map(function(item, i) { return (
{item}
); }, this); return (
{items}
); } ``` ### Animating One or Zero Items Although in the example above we rendered a list of items into `ReactCSSTransitionGroup`, the children of `ReactCSSTransitionGroup` can 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, with the new element animating in while the current animates out. For example, we can implement a simple image carousel like this: ```javascript{10-12} var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup; var ImageCarousel = React.createClass({ propTypes: { imageSrc: React.PropTypes.string.isRequired }, render: function() { return (
); } }); ``` ### 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` `ReactTransitionGroup` is the basis for animations. When children are declaratively added or removed from it (as in the example above) special lifecycle hooks are called on them. ### `componentWillEnter(callback)` This is called at the same time as `componentDidMount()` for components added to an existing `TransitionGroup`. It will block other animations from occurring until `callback` is called. It will not be called on the initial render of a `TransitionGroup`. ### `componentDidEnter()` This is called after the `callback` function that was passed to `componentWillEnter` is called. ### `componentWillLeave(callback)` This is called when the child has been removed from the `ReactTransitionGroup`. Though the child has been removed, `ReactTransitionGroup` will keep it in the DOM until `callback` is called. ### `componentDidLeave()` This is called when the `willLeave` `callback` is called (at the same time as `componentWillUnmount`). ### Rendering a Different Component By default `ReactTransitionGroup` renders as a `span`. You can change this behavior by providing a `component` prop. For example, here's how you would render a `