在構(gòu)建應(yīng)用程序時,動畫是改善整體用戶體驗的好方法,因為它們允許應(yīng)用程序和用戶之間進行更好的交互。
在我們之前的一些 React 教程中,您熟悉了基本的 React 概念,例如 JSX、路由和表單。在本教程中,我們將把它提升到一個新的水平,并嘗試?yán)斫?React 中的動畫。雖然有很多方法可以向 React 應(yīng)用程序添加動畫,但我們將在本文中重點介紹 React transition Group 以及如何使用它。
React 中的動畫
React 提供了許多用于動畫 React 應(yīng)用程序的附加實用程序,其中之一稱為 React Transition Group,由 React 開發(fā)團隊創(chuàng)建。
它不是一個設(shè)置動畫樣式的庫;相反,它是一個具有四種類型內(nèi)置組件的低級 API:Transition、cssTransition、SwitchTransition 和 TransitionGroup。因此,在狀態(tài)更改期間將 React 組件動畫移入和移出 dom 非常簡單。
React Transition Group 是一個非常簡單的入門工具,而且由于它是輕量級的,因此可以減少對樣板代碼的需求,從而加快開發(fā)過程。
開始使用
首先,讓我們在終端中使用 create-react-app 包安裝 react 。
npx create-react-app react-animations
打開公共文件夾的index.html文件并編輯標(biāo)題,如下所示:
<title>TutsPlus - React Animations</title>
讓我們在應(yīng)用程序的 src 文件夾中創(chuàng)建一個名為 components 的文件夾,并創(chuàng)建一個 Home.js 文件。接下來,我們通過創(chuàng)建一個名為 Home 的功能組件并渲染一個 h2 標(biāo)簽來更新此文件。
import React from "react"; const Home = () => { return ( <h2>{"TutsPlus - Welcome to React Animations!"}</h2> > ); }; export default Home;
接下來,通過導(dǎo)入 Home 組件來更新 App.js 文件:
import React from "react"; import Home from "./components/Home"; const App = () => { return ( <home></home>> ); }; export default App;
然后,通過運行以下命令啟動開發(fā)服務(wù)器:
npm run start
反應(yīng)過渡組設(shè)置
讓我們首先在 React 中嘗試一個簡單的動畫,方法是將 react-transition-group 包安裝到項目中。
npm install react-transition-group
接下來,我們從 Home.js 文件中的 react-transition-group 包導(dǎo)入前面提到的四個組件。
import {Transition, CSSTransition, SwitchTransition, TransitionGroup} from "react-transition-group";
接下來,我們將了解每個組件的工作原理。
轉(zhuǎn)換組件
Transition 組件提供了一個 API,用于定義組件在安裝和卸載期間從一種狀態(tài)到另一種狀態(tài)的轉(zhuǎn)換。
現(xiàn)在,在 Home 組件中,將 h2 標(biāo)簽包裝在 Transition 組件中,并像這樣更新代碼。
import React, { useState } from "react"; 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 Home = () => { const [inProp, setInProp] = useState(false); return ( <div> <transition in="{inProp}" timeout="{300}"> {(state) => ( <h2 style="{{" ...defaultstyle ...transitionstyles> {"TutsPlus - Welcome to React Animations"} </h2> )} </transition><button onclick="{()"> setInProp(!inProp)}> Click to {inProp ? "Exit" : "Enter"} </button> </div> > ); }; export default Home;
使用 Transition 標(biāo)簽,我們定義了動畫發(fā)生的部分。我們還使用 inProp 狀態(tài)為轉(zhuǎn)換指定了 in 屬性,這會切換轉(zhuǎn)換狀態(tài)。
正如您所注意到的,我們在上面的 defaultStyle 和 Transition 組件中使用 timeout 屬性指定了動畫持續(xù)時間。這是因為 React 就是這樣知道何時從元素中刪除動畫類以及何時從 DOM 中刪除元素的。
保存以上更改并刷新頁面。頁面加載后,幾秒鐘內(nèi)您就應(yīng)該能夠看到動畫文本。
CSSTransition 組件
當(dāng)嘗試在 React 組件中實現(xiàn)基于 CSS 的動畫時,CSSTransition 組件會派上用場。
因為該組件基于 Transition 組件,所以它繼承了該組件的所有 props,并且還使用幾個類來定義轉(zhuǎn)換。
要了解其工作原理,我們將以下代碼添加到 index.css 文件中,如下所示:
.react-animations-enter { opacity: 0; } .react-animations-enter-active { opacity: 1; transition: opacity 200ms; } .react-animations-exit { opacity: 1; } .react-animations-exit-active { opacity: 0; transition: opacity 200ms; }
從 *-enter 到 *-exit-active,每個類定義了組件處于“進入”、“進入”、“退出”時的轉(zhuǎn)換,和“退出”狀態(tài)。
然后,在 Home.js 中,我們將組件內(nèi)容包裝到 CSSTransition 標(biāo)簽中,傳入 in 和 timeout 屬性以及我們之前定義的類:
<div> <csstransition in="{displayText}" timeout="{300}" classnames="react-animations" unmountonexit><h2>{"TutsPlus - Welcome to CSSTransition"}</h2> </csstransition><button onclick="{()"> setDisplayText(!displayText)}> Display Text </button> </div>
請注意,上面的 classNames 屬性有一個 react-animations 值,該值適用于定義的所有類。
SwitchTransition 類
顧名思義,當(dāng)您想要根據(jù)選定的模式(輸入-輸出或輸出-輸入)在狀態(tài)轉(zhuǎn)換之間切換渲染時,此組件非常有用。當(dāng)您希望一個組件在插入另一個組件時淡出時,它會很有用。
要訪問此實用程序的屬性,我們還將組件的內(nèi)容包裝在 SwitchTransition 標(biāo)記中。還需要注意的是,SwitchTransition 應(yīng)與 Transition 或 CSSTransition 組件一起使用。
讓我們將以下代碼添加到 index.css 文件中,如下所示來創(chuàng)建我們的類:
.fade-enter{ opacity: 0; } .fade-exit{ opacity: 1; } .fade-enter-active{ opacity: 1; } .fade-exit-active{ opacity: 0; } .fade-enter-active, .fade-exit-active{ transition: opacity 500ms; }
讓我們看看它是如何工作的,從 out-in 模式開始,這是默認模式:
const [state, setState] = useState(false); <switchtransition><csstransition key="{state" you enjoy our tutorial : to tutsplus addendlistener="{(node," done> node.addEventListener("transitionend", done, false)} classNames='fade' > <button onclick="{()"> setState(state => !state)}> {state ? "Did you Enjoy our Tutorial?" : "Welcome to TutsPlus"} </button> </csstransition></switchtransition>
上面代碼中的 key 屬性會跟蹤組件中的狀態(tài),而 addEndListener 屬性會阻止組件幾乎立即翻轉(zhuǎn)。如果沒有它,看起來就像沒有實現(xiàn)動畫一樣。
接下來是輸入輸出模式,其中 SwitchTransition 標(biāo)記采用 mode 屬性以及 in-out 值。現(xiàn)在更新您的代碼以查看其工作原理:
<switchtransition mode='{"in-out"}'> {Code goes here} </switchtransition>
過渡組
該組件有助于管理列表中的 Transition 或 CSSTransition 組件。以下是如何應(yīng)用它的示例。
像這樣更新Home.js:
const [items, setItems] = useState(["Manal"]); const CONTACTS = ["Jane", "Fred", "John", "Doe", "Brown"]; const onAddContacts = () => { const newItem = CONTACTS.find((item) => !items.includes(item)); if (newItem) { setItems((prev) => [...prev, newItem]); } }; <div> <transitiongroup><h2>Contacts</h2> {items.map((item, index) => ( <csstransition key="{index}" timeout="{900}" classnames="fade"><p>{item}</p> </csstransition> ))} <button onclick="{onAddContacts}">Add a Contact</button> </transitiongroup> </div>
保存以上內(nèi)容并刷新頁面。單擊該按鈕,該項目應(yīng)添加到帶有動畫的列表中。
從上面的代碼中,我們初始化了一個名為 CONTACTS 的靜態(tài) data 集。然后,定義了一個 onAddContacts 函數(shù),該函數(shù)將處理添加新聯(lián)系人的操作,并在按鈕上觸發(fā)。
列表中的每個項目都包含在 CSSTransition 標(biāo)記中,以對新插入的項目進行動畫處理。最后,該組件被包裝在 TransitionGroup 組件中以管理其中包含的轉(zhuǎn)換。
這是完整的 Home.js 組件:
import React, { useState } from "react"; import { Transition, CSSTransition, SwitchTransition, TransitionGroup } 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 Home = () => { const [inProp, setInProp] = useState(false); const [displayText, setDisplayText] = useState(false); const [state, setState] = useState(false); const [items, setItems] = useState(["Manal"]); const CONTACTS = ["Jane", "Fred", "John", "Doe", "Brown"]; const onAddContacts = () => { const newItem = CONTACTS.find((item) => !items.includes(item)); if (newItem) { setItems((prev) => [...prev, newItem]); } }; return ( <div> <transition in="{inProp}" timeout="{300}"> {(state) => ( <h2 style="{{" ...defaultstyle ...transitionstyles> {"TutsPlus - Welcome to React Animations"} </h2> )} </transition><button onclick="{()"> setInProp(!inProp)}> Click to {inProp ? "Exit" : "Enter"} </button> </div> <div> <csstransition in="{displayText}" timeout="{300}" classnames="react-animations" unmountonexit><h2>{"TutsPlus - Welcome to CSSTransition"}</h2> </csstransition><button onclick="{()"> setDisplayText(!displayText)}> Display Text </button> </div> <div> <switchtransition mode='{"in-out"}'><csstransition key="{state" you enjoy our tutorial : to tutsplus addendlistener="{(node," done> node.addEventListener("transitionend", done, false) } classNames="fade" > <button onclick="{()"> setState((state) => !state)}> {state ? "Did you Enjoy our Tutorial?" : "Welcome to TutsPlus"} </button> </csstransition></switchtransition> </div> <div> <transitiongroup><h2>Contacts</h2> {items.map((item, index) => ( <csstransition key="{index}" timeout="{900}" classnames="fade"><p>{item}</p> </csstransition> ))} <button onclick="{onAddContacts}">Add a Contact</button> </transitiongroup> </div> > ); }; export default Home;
總結(jié)
在本教程中,您了解了如何開始在 React 中使用動畫。您創(chuàng)建了一個簡單的 React 應(yīng)用程序,并了解了如何實現(xiàn)四個 React Transition Group 組件。有關(guān) React 動畫的深入信息,我建議閱讀官方文檔。
本教程的源代碼可在 github 上獲取。