这里记录一篇 React 实现动画效果的学习笔记,文章首发在我的博客站点 www.mayihahaha.com,欢迎吐槽。css
TransitionGroup 是 React 提供的帮助实现动画效果的组件库,这里使用一个简单的 Demo 实践来演示这个库的使用。react
未加动画效果的项目地址: github.com/wewin11235/…, 以这个项目为基础加上动画效果,读者能够自行 clone 并按照 README 文档在本地运行。git
在这个 todoList 应用中但愿在添加或者删除一个 todo 项的时候加上淡入淡出的效果,而不是生硬的在页面上加入或者移除某一项。github
使用前,首先须要安装 react-addons-css-transition-group
:npm
npm i react-addons-css-transition-group -D
复制代码
要实现目标,只须要修改 todoList.js
文件:redux
import React from 'react';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import TodoItem from './todoItem.js';
import { toggleTodo, removeTodo } from '../actions.js';
import { FilterTypes } from '../../constants.js';
import TransitionGroup from 'react-addons-css-transition-group'; // 引入 ReactCssTransitionGroup, TransitionGroup 这个名字能够任意明明,由于须要的这个组件是 export default 的方式引入的
import './todoItem.css'; // 添加对应的 css
const TodoList = ({todos, onToggleTodo, onRemoveTodo}) => {
return (
<ul>
<TransitionGroup transitionName="fade" transitionEnterTimeout={500}
transitionLeaveTimeout={200}>
{
todos.map((item) => (
<TodoItem
key={item.id}
text={item.text}
completed={item.completed}
onToggle={() => onToggleTodo(item.id)}
onRemove={() => onRemoveTodo(item.id)}
/>
))
}
</TransitionGroup>
</ul>
);
};
.....
复制代码
这里咱们使用 TransitionGroup
包裹 TodoItem 组件数组,transitionName="fade" 表明这个TransitionGroup
相关的动画 CSS 的 class 都要以 fade 为前缀。数组
添加 CSS 文件 todoItem.css
:bash
.fade-enter {
opacity: 0.01;
}
.fade-enter.fade-enter-active {
opacity: 1;
transition: opacity 500ms ease-in;
}
.fade-leave {
opacity: 1;
}
.fade-leave.fade-leave-active {
opacity: 0.01;
transition: opacity 200ms ease-in;
}
复制代码
从 css 文件中能够看出,这里的 css class 都是 fade 为前缀(和 transitionName 的值一致),启动项目后,增长和删除代办事项会有动画效果,而且这里的 css class 是由 fade
enterleave
active
这些关键字按照规则组成的。app
经过上面的例子能够看出,ReactCSSTransitionGroup 须要依赖按照必定规则命名的 css class。在组件生命周期的不一样阶段使用不一样规则的 CSS 来达到动画效果。post
CSS 的类名须要以 transitionName 的值开头(如上例中的 fade),后面还有 enter、leave、active 这些关键字,用 - 链接。enter 表明 “装载” 开始时的状态,leave 表示 “卸载”开始时的状态,active 表明动画结束使用的状态。假设 transitionName 的值为 sample 那么相关的类名以下:
sample-enter
sample-enter-active
sample-leave
sample-leave-active
复制代码
其中 sample-enter 和 sample-enter-active 是一对,实现了组件 “装载” 时候的动画效果,sample-leave 和 sample-leave-active 是一对,实现了组件 “卸载” 时候的动画。须要知道的是 enter 和 enter-active 并非同时加到组件上的,由于 CSS3 的动画效果须要明确知道 CSS 的开始和结束时候的样式才能完成过分过程(不明白这个的须要学习下 CSS3 动画的相关知识点),因此对于载入而言,React 先让组件拥有 fade-enter 类,在 JavsScript 的下一个时钟周期才加上 fade-enter-active 类,这样就可使用指定的动画过分方法,完成一个动画效果。对于“卸载” 过程也同样。
TransitionGroup 动画的时长在两个地方都须要指定, 一个是 TransitionGroup 中以 Timeout 为结尾的属性(如上例中的 transitionEnterTimeout 和 transitionLeaveTimeout),第二个地方是 transition-duration 规则,即 CSS 里面。
通常来讲这两处的值应该一致,分别来看看这两处值有何区别。
以上例中的 Todo 应用的 enter 过程为例,TransitionEnterTimeout 表示给组件加上 fade-enter 和 fade-enter-active 类 500 毫秒后就会把这两个类删除掉。CSS 中的规则表示在 500 毫秒内将动画按照指定的节奏运行完毕。因此当 TransitionEnterTimeout 小于 CSS 中指定的过分时间时,动画效果就会中途结束,并以普通效果展现出来。
TransitionGroup 须要先加载完自身才能渲染内部组件。如上例中须要给一个数量变化的组件集体作动画的时候,TransitionGroup 须要包住这整个集合,这就是为了防止 TransitionGroup 自身没有渲染完带来的错误。
如上例子中,todo 列表并不会在首次渲染到页面时候加载动画效果,只有在 todo 新加入(enter)和 删除(leavel)时候才会被调用,要想初次加载也有动画效果就须要 appear。
<TransitionGroup transitionName="fade" transitionAppear={true} transitionAppearTimeout={500}>
复制代码
不一样于 enter 和 leavel, appear 须要有 transitionAppear={true} 的设置才能启用,这是由于 transitionEnter transitionLeavel 默认值为 true,transitionAppear 默认值为 false。appear 的 CSS 写法规则和 enter、leavel 同样。