动画是现代 Web 应用程序的一个令人兴奋的功能。它给应用程序带来了清爽的感觉。React 社区提供了许多优秀的基于 React 的动画库,如 React Motion、React Reveal、react-animations 等,React 本身提供了一个动画库,React Transition Group作为附加选项更早。它是一个独立的库,增强了该库的早期版本。让我们在本章学习 React Transition Group 动画库。
React过渡组
React Transition Group库是一个简单的动画实现。它不做任何开箱即用的动画。相反,它公开了核心动画相关信息。每个动画基本上都是元素从一种状态到另一种状态的过渡。该库公开了每个元素的最小可能状态,它们在下面给出 –
- 进入Entering
- 进入Entered
- 退出Exiting
- 退出Exited
该库提供了为每个状态设置 CSS 样式的选项,并在元素从一种状态移动到另一种状态时根据样式为元素设置动画。该库提供了道具来设置元素的当前状态。如果in props 值为 true,则表示元素正在从进入状态移动到退出状态。如果 in props 的值为 false,则表示元素正在从退出移动到退出。
过渡
过渡是React 过渡组提供的用于动画元素的基本组件。让我们创建一个简单的应用程序并尝试使用Transition 元素淡入/淡出元素。
首先,按照创建 React 应用程序章节中的说明,使用Create React App或Rollup bundler创建一个新的 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() { return ( ); }
接下来,添加过渡组件。将this.state.inProp用于in道具,将 this.duration用于timeout 道具。转换组件需要一个返回用户界面的函数。它基本上是一个渲染道具。
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,回车。
单击删除链接将从 redux 商店中删除该项目。
CSS过渡
CSSTransition建立在Transition组件之上,它通过引入classNames属性改进了Transition组件。classNames属性是指用于元素各种状态的 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() { 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是一个容器组件,它管理一个列表中的多个过渡组件。例如,虽然列表中的每个项目都使用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>