ReactJS - 动画
动画是现代 Web 应用程序的一个令人兴奋的功能。它给应用程序带来了耳目一新的感觉。React 社区提供了许多基于 React 的优秀动画库,如 React Motion、React Reveal、react-animations 等,React 本身提供了一个动画库 React Transition Group,作为早期的附加选项。它是一个独立的库,增强了早期版本的库。让我们在本章中学习 React Transition Group 动画库。
React Transition Group
React Transition Group 库是动画的简单实现。它不执行任何开箱即用的动画。相反,它公开了核心动画相关信息。每个动画基本上都是元素从一个状态到另一个状态的过渡。该库公开了每个元素的最小可能状态,如下所示 −
- Entering
- Entered
- Exiting
- Exited
该库提供了设置每个状态的 CSS 样式的选项,并在元素从一个状态移动到另一个状态时根据样式为元素设置动画。该库提供了 in props 来设置元素的当前状态。如果 in props 值为 true,则表示元素正在从 entering 状态移动到 exiting 状态。如果 props 值为 false,则表示元素正在从 exiting 移动到 exited。
安装
要安装此 React Transition Group 库,请使用以下任一命令 −
# npm npm install react-transition-group --save # yarn yarn add react-transition-group
Transition
Transition 是 React Transition Group 提供的用于为元素设置动画的基本组件。让我们创建一个简单的应用程序,并尝试使用 Transition 元素 淡入/淡出元素。
首先,按照创建 React 应用程序一章中的说明,使用 Create React App 或 Rollup 捆绑器创建一个新的 React 应用程序 react-animation-app。
接下来,安装 React Transition Group 库。
cd /go/to/project npm install react-transition-group --save
接下来,在您最喜欢的编辑器中打开该应用程序。
接下来,在应用程序的根目录下创建 src 文件夹。
接下来,在 src 文件夹下创建 components 文件夹。
接下来,创建一个文件, src/components 文件夹下的 HelloWorld.js 并开始编辑。
接下来,导入 React 和动画库。
import React from 'react'; import { Transition } from 'react-transition-group'
接下来,创建 HelloWorld 组件。
class HelloWorld extends React.Component { constructor(props) { super(props); } }
接下来,在构造函数中将过渡相关样式定义为 JavaScript 对象。
this.duration = 2000; this.defaultStyle = { transition: `opacity ${this.duration}ms ease-in-out`, opacity: 0, } this.transitionStyles = { entering: { opacity: 1 }, entered: { opacity: 1 }, exiting: { opacity: 0 }, exited: { opacity: 0 }, };
这里,
defaultStyles设置过渡动画
transitionStyles设置各种状态的样式
接下来,在构造函数中设置元素的初始状态。
this.state = { inProp: true }
接下来,通过每 3 秒更改一次 inProp 值来模拟动画。
setInterval(() => { this.setState((state, props) => { let newState = { inProp: !state.inProp }; return newState; }) }, 3000);
接下来,创建一个 render 函数。
render() { return ( ); }
接下来,添加 Transition 组件。使用 this.state.inProp 作为 in 属性,使用 this.duration 作为 timeout 属性。Transition 组件需要一个函数,该函数返回用户界面。它基本上是一个 Render props。
render() { return ( <Transition in={this.state.inProp} timeout={this.duration}> {state => ({ ... component's user interface. }) </Transition> ); }
接下来,在容器内编写组件用户界面,并为容器设置 defaultStyle 和 transitionStyles。
render() { return ( <Transition in={this.state.inProp} timeout={this.duration}> {state => ( <div style={{ ...this.defaultStyle, ...this.transitionStyles[state] }}> <h1>Hello World!</h1> </div> )} </Transition> ); }
最后,暴露组件。
export default HelloWorld
组件完整源代码如下 −
import React from "react"; import { Transition } from 'react-transition-group'; class HelloWorld extends React.Component { constructor(props) { super(props); this.duration = 2000; this.defaultStyle = { transition: `opacity ${this.duration}ms ease-in-out`, opacity: 0, } this.transitionStyles = { entering: { opacity: 1 }, entered: { opacity: 1 }, exiting: { opacity: 0 }, exited: { opacity: 0 }, }; this.state = { inProp: true } setInterval(() => { this.setState((state, props) => { let newState = { inProp: !state.inProp }; return newState; }) }, 3000); } render() { return ( <Transition in={this.state.inProp} timeout={this.duration}> {state => ( <div style={{ ...this.defaultStyle, ...this.transitionStyles[state] }}> <h1>Hello World!</h1> </div> )} </Transition> ); } } export default HelloWorld;
接下来,在 src 文件夹下创建一个文件 index.js,并使用 HelloWorld 组件。
import React from 'react'; import ReactDOM from 'react-dom'; import HelloWorld from './components/HelloWorld'; ReactDOM.render( <React.StrictMode <HelloWorld / </React.StrictMode , document.getElementById('root') );
最后,在根文件夹下创建public文件夹,并创建index.html文件。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>React Containment App</title> </head> <body> <div id="root"></div> <script type="text/JavaScript" src="./index.js"></script> </body> </html>
接下来,使用 npm 命令为应用程序提供服务。
npm start
接下来,打开浏览器并在地址栏中输入 http://localhost:3000,然后按 Enter。
单击删除链接将从 redux 商店中删除该项目。

要了解有关使用 React Transition Group 为元素设置动画的更多信息,请单击此处。
CSSTransition
CSSTransition 建立在 Transition 组件之上,它通过引入 classNames 属性改进了 Transition 组件。 classNames prop 指的是元素各种状态所用的 css 类名。
例如,classNames=hello prop 指的是下面的 css 类。
.hello-enter { opacity: 0; } .hello-enter-active { opacity: 1; transition: opacity 200ms; } .hello-exit { opacity: 1; } .hello-exit-active { opacity: 0; transition: opacity 200ms; }
让我们使用 CSSTransition 组件创建一个新组件 HelloWorldCSSTransition。
首先,在您最喜欢的编辑器中打开我们的 react-animation-app 应用程序。
接下来,在 src/components 文件夹下创建一个新文件 HelloWorldCSSTransition.css,并输入过渡类。
.hello-enter { opacity: 1; transition: opacity 2000ms ease-in-out; } .hello-enter-active { opacity: 1; transition: opacity 2000ms ease-in-out; } .hello-exit { opacity: 0; transition: opacity 2000ms ease-in-out; } .hello-exit-active { opacity: 0; transition: opacity 2000ms ease-in-out; }
接下来,在 src/components 文件夹下创建一个新文件 HelloWorldCSSTransition.js 并开始编辑。
接下来,导入 React 和动画库。
import React from 'react'; import { CSSTransition } from 'react-transition-group'
接下来,导入 HelloWorldCSSTransition.css。
import './HelloWorldCSSTransition.css'
接下来,创建 HelloWorld 组件。
class HelloWorldCSSTransition extends React.Component { constructor(props) { super(props); } }
接下来,在构造函数中定义过渡的持续时间。
this.duration = 2000;
接下来,在构造函数中设置元素的初始状态。
this.state = { inProp: true }
接下来,通过每 3 秒更改一次 inProp 值来模拟动画。
setInterval(() => { this.setState((state, props) => { let newState = { inProp: !state.inProp }; return newState; }) }, 3000);
接下来,创建一个 render 函数。
render() { return ( ); }
接下来,添加 CSSTransition 组件。使用 this.state.inProp 作为 in 属性,使用 this.duration 作为 timeout 属性,使用 hello 作为 classNames 属性。CSSTransition 组件需要将用户界面作为子属性。
render() { return ( <CSSTransition in={this.state.inProp} timeout={this.duration} classNames="hello"> // ... user interface code ... </CSSTransition> ); }
接下来,编写组件的用户界面。
render() { return ( <CSSTransition in={this.state.inProp} timeout={this.duration} classNames="hello"> <div> <h1>Hello World!</h1> </div> </CSSTransition> ); }
最后,暴露组件。
export default HelloWorldCSSTransition;
下面给出了该组件的完整源代码 −
import React from 'react'; import { CSSTransition } from 'react-transition-group' import './HelloWorldCSSTransition.css' class HelloWorldCSSTransition extends React.Component { constructor(props) { super(props); this.duration = 2000; this.state = { inProp: true } setInterval(() => { this.setState((state, props) => { let newState = { inProp: !state.inProp }; return newState; }) }, 3000); } render() { return ( <CSSTransition in={this.state.inProp} timeout={this.duration} classNames="hello"> <div> <h1>Hello World!</h1> </div> </CSSTransition> ); } } export default HelloWorldCSSTransition;
接下来,在 src 文件夹下创建一个文件 index.js,并使用 HelloWorld 组件。
import React from 'react'; import ReactDOM from 'react-dom'; import HelloWorldCSSTransition from './components/HelloWorldCSSTransition'; ReactDOM.render( <React.StrictMode> <HelloWorldCSSTransition /> </React.StrictMode>, document.getElementById('root') );
接下来,使用 npm 命令为应用程序提供服务。
npm start
接下来,打开浏览器并在地址栏中输入 http://localhost:3000 并按回车键。
消息将每 3 秒淡入淡出一次。

TransitionGroup
TransitionGroup 是一个容器组件,它管理列表中的多个过渡组件。例如,虽然列表中的每个项目都使用 CSSTransition,但 TransitionGroup 可用于对所有项目进行分组以实现适当的动画。
<TransitionGroup> {items.map(({ id, text }) => ( <CSSTransition key={id} timeout={500} classNames="item" > <Button onClick={() => setItems(items => items.filter(item => item.id !== id) ) } > × </Button> {text} </CSSTransition> ))} </TransitionGroup>