likes
comments
collection
share

(32)React 拓展——② 使用 react-transition-group 实现动画 | React 基础理论实操

作者站长头像
站长
· 阅读数 4
转载请注明出处,未经同意,不可修改文章内容。

🔥🔥🔥“前端一万小时”两大明星专栏——“从零基础到轻松就业”、“前端面试刷题”,已于本月大改版,合二为一,干货满满,欢迎点击公众号菜单栏各模块了解。

1 CSSTransition

紧接上一篇代码,本篇我们用 React 动画的第三方模块 react-transition-group 来轻松实现更加复杂的动画效果。

1️⃣安装这个模块:

npm install react-transition-group --save

(32)React 拓展——② 使用 react-transition-group 实现动画 | React 基础理论实操

2️⃣本节我们主要讲解 CSSTransition 的使用(Transition 是更底层的组件,当 CSSTransition 实现不了我们的需求时,可以去查查 Transition 的 API。而 TransitionGroup 的话,我们会在下一节讲解!),跟着官方文档的“例子”进行操作: (32)React 拓展——② 使用 react-transition-group 实现动画 | React 基础理论实操

打开 App.js 文件:

import React, { Component, Fragment } from "react";  

// 2️⃣-①:引入 CSSTransition 动画组件;
import { CSSTransition } from 'react-transition-group';  

import "./style.css";

class App extends Component  {
  constructor(props) { 
    super(props);
    
    this.state = {
      show: true  
    }
    
    this.handleBtnToggle = this.handleBtnToggle.bind(this); 
  }
  
  render() {
    return (
      <Fragment>
      
        {/*
         ❗️❗️❗️2️⃣-②:有了 CSSTransition 后,我们就不需要自己去进行样式的添加和移除了!
        <div className={this.state.show ? "show" : "hide"}>hello, qdywxs.</div>
          */}
      
        {/*
         2️⃣-③:取而代之,我只需要在 div 元素的外层嵌套一个 CSSTransition 组件即可。
         CSSTransition 会自动帮我们做一些 class 的增加、移除的工作;
          */}
        <CSSTransition>
          <div>hello, qdywxs.</div>
			  </CSSTransition>
 
        <button onClick={this.handleBtnToggle}>toggle</button>
      </Fragment>
    );
  }
  
  handleBtnToggle() {
    this.setState({
      show: this.state.show ? false : true
    })
  }
}

export default App;

❗️❗️❗️2️⃣-④:接着需要对 CSSTransition 做一些设置; (32)React 拓展——② 使用 react-transition-group 实现动画 | React 基础理论实操

🚀在具体的代码编写之前,我们先熟悉一下基本的理论知识:

1. CSSTransition 组件中重要的 API 解析
  • in :Boolean,控制组件显示与隐藏。 true 显示, false 隐藏;

  • timeout :Number,延迟,涉及到动画状态的持续时间。可传入一个对象,如 {exit: 300, enter: 500} 来分别设置“入”和“离开”的延时;

  • classNames :String,动画进行时给元素添加的类名。一般利用这个属性来设计动画!(❗️特别注意:是 classNames 而不是 className !)

  • unmountOnExit :Boolean,这是一个很实用的 API,它为我们节省了很多精力。为 true 时——组件为隐藏状态时移除组件;为 false 时——组件保持动画结束时的状态而不移除元素(一般要设成 true )。

2. 类名的添加

动画进行时,以 classNames="fade" 为例,CSSTransition 将自动依次为要执行动画的元素添加以下类名:

  • fade-enter

  • fade-enter-active

  • fade-enter-done

  • fade-exit

  • fade-exit-active

  • fade-exit-done

我们也可以单独指定每一个类名:

classNames={{
	enter: "my-enter",
  enterActive: "my-active-enter",
  enterDone: "my-done-enter",
  
  exit: "my-exit",
  exitActive: "my-active-exit",
  exitDone: "my-done-exit"
}}
3. 每个类名的添加时机
  • enter :当元素进入时添加;

  • enter-active :当元素进入到页面后添加。它与 enter 的主要差别是—— enter-active 是在元素已经添加到页面后才会添加 enter-active ,而 enter 在元素添加到页面时已经携带;

  • enter-done :动画执行完毕后添加。动画时长取决于 timeout

  • exit :元素离开时添加。离开动画时长取决于 timeout

  • exit-active :同 exit

  • exit-done :离开动画完成后添加(仅在 unmountOnExitfalse 时有效)。

2️⃣-⑤:基础理论知识介绍完后,我们直奔 App.js 文件进行代码的编写;

import React, { Component, Fragment } from "react";  

import { CSSTransition } from 'react-transition-group';  

import "./style.css";

class App extends Component  {
  constructor(props) { 
    super(props);
    
    this.state = {
      show: true  
    }
    
    this.handleBtnToggle = this.handleBtnToggle.bind(this); 
  }
  
  render() {
    return (
      <Fragment>
      
      	{/* ❗️2️⃣-⑥:对 CSSTransition 进行设置; */}
        <CSSTransition
          in={this.state.show}
      		timeout={1000}
  				classNames="fade"
					unmountOnExit={true}
        >
            
          <div>hello, qdywxs.</div>
			  </CSSTransition>
 
        <button onClick={this.handleBtnToggle}>toggle</button>
      </Fragment>
    );
  }
  
  handleBtnToggle() {
    this.setState({
      show: this.state.show ? false : true
    })
  }
}

export default App;

❗️❗️❗️2️⃣-⑦:打开 style.css 文件(清空之前的代码),我们在里边定义动画“进行时”各阶段的效果(🏆CSSTransition 已自动为我们添加了动画各阶段对应的 class ,我们只需要给各 class 添加对应的效果即可);

.fade-enter {
  opacity: 0;
}
.fade-enter-active {
  opacity: 1;
  transition: opacity 1s ease-in;
}
fade-enter-done {
  opacity: 1;
}

.fade-exit {
  opacity: 1;
}
.fade-exit-active {
  opacity: 0;
  transition: opacity 1s ease-in;
}
fade-exit-done {
  opacity: 0;
}

返回页面查看效果: (32)React 拓展——② 使用 react-transition-group 实现动画 | React 基础理论实操

3️⃣我们继续查阅官方文档,拉到最下边,官方为我们提供了很多“钩子函数”。“钩子函数”是什么?它是会在适当的时候自动执行的函数! (32)React 拓展——② 使用 react-transition-group 实现动画 | React 基础理论实操

利用这些“钩子函数”,我们就可以用 JS 来控制一些样式了。如(打开 App.js 文件):

import React, { Component, Fragment } from "react";  

import { CSSTransition } from 'react-transition-group';  

import "./style.css";

class App extends Component  {
  constructor(props) { 
    super(props);
    
    this.state = {
      show: true  
    }
    
    this.handleBtnToggle = this.handleBtnToggle.bind(this); 
  }
  
  render() {
    return (
      <Fragment>

        {/*
         ❗️❗️❗️在这里定义一个“钩子函数”,当“入场动画”结束之后,
         onEntered 自动执行!
         ❗️里边的参数 el 指的就是 CSSTransition 内部包裹的这个 div 元素!
          */}
        <CSSTransition
          in={this.state.show}
          timeout={1000}
          classNames="fade"
          unmountOnExit={true}

          onEntered={(el) => {
            el.innerHTML="hello, 前端一万小时.";
            el.style.color="red";
          }}
        >  
            
          <div>hello, qdywxs.</div>
        </CSSTransition>
 
        <button onClick={this.handleBtnToggle}>toggle</button>
      </Fragment>
    );
  }
  
  handleBtnToggle() {
    this.setState({
      show: this.state.show ? false : true
    })
  }
}

export default App;

返回页面查看效果: (32)React 拓展——② 使用 react-transition-group 实现动画 | React 基础理论实操

❓4️⃣上边的动画效果有个问题:页面初次打开时(刷新页面),动画效果是不执行的!怎样解决这个问题呢?

答:CSSTransition 的 appear 属性可以帮助我们实现——页面一打开,动画效果就生效!

打开 App.js 文件:

import React, { Component, Fragment } from "react";  

import { CSSTransition } from 'react-transition-group';  

import "./style.css";

class App extends Component  {
  constructor(props) { 
    super(props);
    
    this.state = {
      show: true  
    }
    
    this.handleBtnToggle = this.handleBtnToggle.bind(this); 
  }
  
  render() {
    return (
      <Fragment>

        {/* ❗️4️⃣-①:增加一个 appear 属性; */}
        <CSSTransition
          in={this.state.show}
          timeout={1000}
          classNames="fade"
          unmountOnExit={true}

					appear={true}

          onEntered={(el) => {
            el.innerHTML="hello, 前端一万小时.";
            el.style.color="red";

          }}
        >  
            
          <div>hello, qdywxs.</div>
        </CSSTransition>
 
        <button onClick={this.handleBtnToggle}>toggle</button>
      </Fragment>
    );
  }
  
  handleBtnToggle() {
    this.setState({
      show: this.state.show ? false : true
    })
  }
}

export default App;

4️⃣-②:当用了 appear 属性后,CSSTransition 会帮助我们干一件事——它会在入场动画的第一帧增加一个名为 fade-appearclass ;还会在整个动画进行过程中增加一个名为 fade-appear-activeclass

打开 style.css 文件:

.fade-enter, .fade-appear { /* ❗️增加 fade-appear */
  opacity: 0;
}
.fade-enter-active, .fade-appear-active { /* ❗️增加 fade-appear-active */
  opacity: 1;
  transition: opacity 1s ease-in;
}
fade-enter-done {
  opacity: 1;
}

.fade-exit {
  opacity: 1;
}
.fade-exit-active {
  opacity: 0;
  transition: opacity 1s ease-in;
}
fade-exit-done {
  opacity: 0;
}

返回页面查看效果: (32)React 拓展——② 使用 react-transition-group 实现动画 | React 基础理论实操

2 TransitionGroup

Transition Group 可以帮助我们实现多个元素的动画效果。

❓需求:紧接上边的代码,当我每点击一次 toggle 按钮时,页面都会相应显示一行 hello, qdywxs. 。且,显示的时候都会有动画效果(入场动画结束后,会变成红色的 hello, 前端一万小时. )。 答:

1️⃣打开 App.js 文件(将里边的代码清空),我们先来实现“点击” --> “显示”的逻辑:

import React, { Component, Fragment } from "react";  

import "./style.css";

class App extends Component  {
  constructor(props) { 
    super(props);
    
    this.state = {
      list:[]
    }
    
    this.handleAddItem = this.handleAddItem.bind(this); 
  }
  
  render() {
    return (
      <Fragment>

        {
          this.state.list.map((item, index) => {
            return (
              <div key={index}>hello, qdywxs.</div>
            )
          })
        }

        <button onClick={this.handleAddItem}>toggle</button>

      </Fragment>
    );
  }
  
  handleAddItem() {
    this.setState((prevState) => {
      return {
        list: [...prevState.list, "item"]
      }
    })
  }
}

export default App;

看下页面效果: (32)React 拓展——② 使用 react-transition-group 实现动画 | React 基础理论实操

2️⃣实现每一项 hello, qdywxs. 出现时,都有动画效果(请对照 TransitionGroup 官方文档学习并自行拓展):

import React, { Component, Fragment } from "react";  

// 2️⃣-①:引入 CSSTransition 和 TransitionGroup 这两个“组件”;
import {
  CSSTransition,
  TransitionGroup,
} from "react-transition-group";

import "./style.css";

class App extends Component  {
  constructor(props) { 
    super(props);
    
    this.state = {
      list:[]
    }
    
    this.handleAddItem = this.handleAddItem.bind(this); 
  }
  
  render() {
    return (
      // 2️⃣-②:参照官方文档例子,给要添加动画的“多个元素”的最外层包裹一个 TransitionGroup 标签;
      /*
      2️⃣-③:给单个元素包裹 CSSTransition 标签(这个和上文讲的做法一模一样,
      可以直接拷贝过来,❗️但要去掉属性 in);
       */
      <Fragment>
        <TransitionGroup>
          {
            this.state.list.map((item, index) => {
              return (
                <CSSTransition
                  timeout={1000}
                  classNames="fade"
                  unmountOnExit={true}

                  appear={true}

                  onEntered={(el) => {
                    el.innerHTML="hello, 前端一万小时.";
                    el.style.color="red";
                  
                  }} 
                  
                  key={index}
                >
                  <div>hello, qdywxs.</div>
                </CSSTransition>
              )
            })
          }
        </TransitionGroup>

        <button onClick={this.handleAddItem}>toggle</button>

      </Fragment>
    );
  }
  
  handleAddItem() {
    this.setState((prevState) => {
      return {
        list: [...prevState.list, "item"]
      }
    })
  }
}

export default App;

返回页面查看效果: (32)React 拓展——② 使用 react-transition-group 实现动画 | React 基础理论实操

祝好,qdywxs ♥ you!

转载自:https://juejin.cn/post/7313589252172021794
评论
请登录