ReactJS - 動畫:讓您的組件活起來

你好,未來的 React 動畫巫師們!我很興奮能成為您們在 ReactJS 動畫世界的導遊。作為一個教了多年計算機科學的人,我可以告訴您,動畫就像是讓您的應用程序從功能性的變得非常吸引人的秘密調味料。所以,讓我們一起潛入水中,讓那些組件跳起舞來!

ReactJS - Animation

React Transition Group 的魔力

在我們開始玩轉動畫之前,讓我們先了解 React Transition Group 是什麼。把它當成一個裝滿了方便小工具的工具箱,幫助我們在 React 應用程序中創建有順暢感、引人注目的過渡效果。

安裝 React Transition Group

首先,我們需要將 React Transition Group 邀請到我們的專案派對中。打開您的終端機並輸入:

npm install react-transition-group

或者如果您是 yarn 的粉絲:

yarn add react-transition-group

太棒了!現在我们在指尖上擁有了動畫的超能力。

Transition:動畫的基石

Transition 組件就像是房子的基礎。它為我們提供了一個堅實的基礎來建立我們的動畫。讓我們用一個簡單的例子來看看它是如何工作的:

import React, { useState } from 'react';
import { Transition } from 'react-transition-group';

const duration = 300;

const defaultStyle = {
transition: `opacity ${duration}ms ease-in-out`,
opacity: 0,
}

const transitionStyles = {
entering: { opacity: 1 },
entered:  { opacity: 1 },
exiting:  { opacity: 0 },
exited:  { opacity: 0 },
};

const FadeInOut = () => {
const [inProp, setInProp] = useState(false);

return (
<div>
<Transition in={inProp} timeout={duration}>
{state => (
<div style={{
...defaultStyle,
...transitionStyles[state]
}}>
我是一個漸變的文本!
</div>
)}
</Transition>
<button onClick={() => setInProp(!inProp)}>
點擊以漸變
</button>
</div>
);
};

讓我們分解一下:

  1. 我們從 'react-transition-group' 引入 Transition
  2. 我們設定了一些樣式:一個 defaultStyle 為我們的初始狀態,和 transitionStyles 為過渡的不同階段。
  3. 我們的 FadeInOut 組件使用一個狀態 inProp 來控制可見性。
  4. Transition 組件接受兩個主要屬性:in(我們的可見性狀態)和 timeout(動畫的持續時間)。
  5. Transition 內部,我們使用一個函數,它接收當前的過渡狀態並應用相應的樣式。

當您點擊按鈕時,您會看到文本平滑地淡入和淡出。神奇,對吧?

CSSTransition:當 CSS 遇上 React

現在,讓我們升級我們的遊戲,使用 CSSTransition。它就像是 Transition 的更酷的兄弟,可以與 CSS 類別無縫工作。這裡有一個有趣的例子:

import React, { useState } from 'react';
import { CSSTransition } from 'react-transition-group';
import './styles.css'; // 我們稍後會創建這個文件

const Superhero = () => {
const [inProp, setInProp] = useState(false);

return (
<div>
<CSSTransition in={inProp} timeout={300} classNames="super">
<div className="superhero">
我是一個超級英雄!
</div>
</CSSTransition>
<button onClick={() => setInProp(!inProp)}>
變身!
</button>
</div>
);
};

這是我們的 CSS(在 styles.css 中):

.superhero {
background-color: #f0f0f0;
padding: 20px;
border-radius: 5px;
}

.super-enter {
opacity: 0;
transform: scale(0.9);
}
.super-enter-active {
opacity: 1;
transform: translateX(0);
transition: opacity 300ms, transform 300ms;
}
.super-exit {
opacity: 1;
}
.super-exit-active {
opacity: 0;
transform: scale(0.9);
transition: opacity 300ms, transform 300ms;
}

這裡發生了什麼:

  1. 我們使用 CSSTransition 而不是 Transition
  2. 我們指定 classNames="super",這告訴 React 使用像 super-entersuper-enter-active 之類的類別。
  3. 我們的 CSS 定義了組件在過渡的每個階段應該看起來如何。

當您點擊 "變身!" 時,我們的超級英雄會有劇烈地出現和消失的縮放效果。就像在瀏覽器中看超級英雄電影一樣!

TransitionGroup:處理多個過渡

最後但同樣重要的是,讓我們來谈谈 TransitionGroup。它就像是樂團中的指揮,同時管理多個過渡。這裡有一個實用的例子:

import React, { useState } from 'react';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import './list-styles.css';

const TodoList = () => {
const [items, setItems] = useState([]);
const [inputValue, setInputValue] = useState('');

const addItem = () => {
setItems([...items, { id: Date.now(), text: inputValue }]);
setInputValue('');
};

const removeItem = (id) => {
setItems(items.filter(item => item.id !== id));
};

return (
<div>
<input
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="輸入一個任務"
/>
<button onClick={addItem}>添加</button>
<TransitionGroup className="todo-list">
{items.map(({ id, text }) => (
<CSSTransition
key={id}
timeout={500}
classNames="item"
>
<div className="todo-item">
{text}
<button onClick={() => removeItem(id)}>X</button>
</div>
</CSSTransition>
))}
</TransitionGroup>
</div>
);
};

對應的 CSS(list-styles.css):

.todo-list {
list-style-type: none;
padding: 0;
}

.todo-item {
background-color: #f9f9f9;
border: 1px solid #ddd;
padding: 10px;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
}

.item-enter {
opacity: 0;
}
.item-enter-active {
opacity: 1;
transition: opacity 500ms ease-in;
}
.item-exit {
opacity: 1;
}
.item-exit-active {
opacity: 0;
transition: opacity 500ms ease-in;
}

這個例子創建了一個簡單的待辦事項列表,當添加或刪除項目時,項目會漸變。這裡的分解:

  1. 我們用 TransitionGroup 包裹我們的項目列表。
  2. 每個項目都用 CSSTransition 包裹。
  3. 當項目被添加或刪除時,TransitionGroup 自動管理過渡。

結果呢?一個平滑、專業看起來的待辦事項列表,任何專案經理都會為之驕傲!

總結

好了,各位!我們一起穿行了 React 動畫的土地,從基本的 Transition 到強大的 TransitionGroup。記住,動畫不僅僅是讓事物看起來漂亮(這是個很好的獎勵),它們是創建有直覺性、響應式的界面,引導用戶通過您的應用程序。

這裡是我們所介紹的方法的快速參考表:

組件 使用案例 鍵屬性
Transition 基本過渡 in, timeout
CSSTransition 基於 CSS 的過渡 in, timeout, classNames
TransitionGroup 管理多個過渡 component(可選)

現在,去動畫化吧!記住,力量越大,責任越大。明智地使用動畫,您的用戶會感謝您的。開心編程!

Credits: Image by storyset