React 動畫效果之 TransitionGroup 的使用

這裏記錄一篇 React 實現動畫效果的學習筆記,文章首發在我的博客站點 www.mayihahaha.com,歡迎吐槽。css

TransitionGroup 是 React 提供的幫助實現動畫效果的組件庫,這裏使用一個簡單的 Demo 實踐來演示這個庫的使用。react

未加動畫效果的項目地址: github.com/wewin11235/…, 以這個項目爲基礎加上動畫效果,讀者能夠自行 clone 並按照 README 文檔在本地運行。git

目標

在這個 todoList 應用中但願在添加或者刪除一個 todo 項的時候加上淡入淡出的效果,而不是生硬的在頁面上加入或者移除某一項。github

TransitionGroup 的使用

使用前,首先須要安裝 react-addons-css-transition-groupnpm

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 規則

經過上面的例子能夠看出,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 同樣。

相關文章
相關標籤/搜索