這裏記錄一篇 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 同樣。