对于实现一个组件的显示与消失的过渡动画,可以通过原生的CSS来实现这些过渡动画,但是React社区为我们提供了react-transition-group库用来完成过渡动画。
# npmnpm install react-transition-group --save# yarnyarn add react-transition-group
CSSTransition是基于Transition组件构建的;
对应三种状态:
- import React, { createRef, PureComponent } from 'react'
- import { CSSTransition } from "react-transition-group"
- import "./style.css"
-
- export class App extends PureComponent {
- constructor(props) {
- super(props)
-
- this.state = {
- isShow: true
- }
-
- this.sectionRef = createRef()
- }
-
- render() {
- const { isShow } = this.state
-
- return (
- <div>
- <button onClick={e => this.setState({isShow: !isShow})}>切换button>
- {/* { isShow && <h2>哈哈哈h2> } */}
-
- <CSSTransition
- nodeRef={this.sectionRef}
- in={isShow}
- unmountOnExit={true}
- classNames="why"
- timeout={2000}
- appear
- onEnter={e => console.log("开始进入动画")}
- onEntering={e => console.log("执行进入动画")}
- onEntered={e => console.log("执行进入结束")}
- onExit={e => console.log("开始离开动画")}
- onExiting={e => console.log("执行离开动画")}
- onExited={e => console.log("执行离开结束")}
- >
- <div className='section' ref={this.sectionRef}>
- <h2>哈哈哈h2>
- <p>我是内容, 哈哈哈p>
- div>
- CSSTransition>
- div>
- )
- }
- }
-
- export default App
- .why-appear, .why-enter {
- opacity: 0;
- }
-
- .why-appear-active, .why-enter-active {
- opacity: 1;
- transition: opacity 2s ease;
- }
-
- /* 离开动画 */
- .why-exit {
- opacity: 1;
- }
-
- .why-exit-active {
- opacity: 0;
- transition: opacity 2s ease;
- }
SwitchTransition可以完成两个组件之间切换的炫酷动画:
- import React, { PureComponent } from 'react'
- import { SwitchTransition, CSSTransition } from 'react-transition-group'
- import "./style.css"
-
- export class App extends PureComponent {
- constructor() {
- super()
-
- this.state = {
- isLogin: true
- }
- }
-
- render() {
- const { isLogin } = this.state
-
- return (
- <div>
- <SwitchTransition mode='out-in'>
- <CSSTransition
- key={isLogin ? "exit": "login"}
- classNames="login"
- timeout={1000}
- >
- <button onClick={e => this.setState({ isLogin: !isLogin })}>
- { isLogin ? "退出": "登录" }
- button>
- CSSTransition>
- SwitchTransition>
- div>
- )
- }
- }
-
- export default App
- .login-enter {
- transform: translateX(100px);
- opacity: 0;
- }
-
- .login-enter-active {
- transform: translateX(0);
- opacity: 1;
- transition: all 1s ease;
- }
-
- .login-exit {
- transform: translateX(0);
- opacity: 1;
- }
-
- .login-exit-active {
- transform: translateX(-100px);
- opacity: 0;
- transition: all 1s ease;
- }
-
将多个动画放到一组动画里执行,通过TransitionGroup组件实现;
例如书籍列表的添加与删除动画,为每个书籍项添加新增与删除动画;
- import React, { PureComponent } from 'react'
- import { TransitionGroup, CSSTransition } from "react-transition-group"
- import "./style.css"
-
- export class App extends PureComponent {
- constructor() {
- super()
-
- this.state = {
- books: [
- { id: 111, name: "你不知道JS", price: 99 },
- { id: 222, name: "JS高级程序设计", price: 88 },
- { id: 333, name: "Vuejs高级设计", price: 77 },
- ]
- }
- }
-
- addNewBook() {
- const books = [...this.state.books]
- books.push({ id: new Date().getTime(), name: "React高级程序设计", price: 99 })
- this.setState({ books })
- }
-
- removeBook(index) {
- const books = [...this.state.books]
- books.splice(index, 1)
- this.setState({ books })
- }
-
- render() {
- const { books } = this.state
-
- return (
- <div>
- <h2>书籍列表:h2>
- <TransitionGroup component="ul">
- {
- books.map((item, index) => {
- return (
- <CSSTransition key={item.id} classNames="book" timeout={1000}>
- <li>
- <span>{item.name}-{item.price}span>
- <button onClick={e => this.removeBook(index)}>删除button>
- li>
- CSSTransition>
- )
- })
- }
- TransitionGroup>
- <button onClick={e => this.addNewBook()}>添加新书籍button>
- div>
- )
- }
- }
-
- export default App
- .book-enter {
- transform: translateX(150px);
- opacity: 0;
- }
-
- .book-enter-active {
- transform: translateX(0);
- opacity: 1;
- transition: all 1s ease;
- }
-
- .book-exit {
- transform: translateX(0);
- opacity: 1;
- }
-
- .book-exit-active {
- transform: translateX(150px);
- opacity: 0;
- transition: all 1s ease;
- }
-