日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

react組件中過渡動(dòng)畫的問題解決_React

作者:別救了這猴子廢了 ? 更新時(shí)間: 2022-11-02 編程語言

一、是什么

在日常開發(fā)中,頁面切換時(shí)的轉(zhuǎn)場(chǎng)動(dòng)畫是比較基礎(chǔ)的一個(gè)場(chǎng)景

當(dāng)一個(gè)組件在顯示與消失過程中存在過渡動(dòng)畫,可以很好的增加用戶的體驗(yàn)

react中實(shí)現(xiàn)過渡動(dòng)畫效果會(huì)有很多種選擇,如react-transition-groupreact-motionAnimated,以及原生的CSS都能完成切換動(dòng)畫

二、如何實(shí)現(xiàn)

react中,react-transition-group是一種很好的解決方案,其為元素添加enterenter-activeexitexit-active這一系列勾子

可以幫助我們方便的實(shí)現(xiàn)組件的入場(chǎng)和離場(chǎng)動(dòng)畫

其主要提供了三個(gè)主要的組件:

  • CSSTransition:在前端開發(fā)中,結(jié)合 CSS 來完成過渡動(dòng)畫效果
  • SwitchTransition:兩個(gè)組件顯示和隱藏切換時(shí),使用該組件
  • TransitionGroup:將多個(gè)動(dòng)畫組件包裹在其中,一般用于列表中元素的動(dòng)畫

CSSTransition

其實(shí)現(xiàn)動(dòng)畫的原理在于,當(dāng)CSSTransitionin屬性置為true時(shí),CSSTransition首先會(huì)給其子組件加上xxx-enterxxx-enter-activeclass執(zhí)行動(dòng)畫

當(dāng)動(dòng)畫執(zhí)行結(jié)束后,會(huì)移除兩個(gè)class,并且添加-enter-doneclass

所以可以利用這一點(diǎn),通過csstransition屬性,讓元素在兩個(gè)狀態(tài)之間平滑過渡,從而得到相應(yīng)的動(dòng)畫效果

當(dāng)in屬性置為false時(shí),CSSTransition會(huì)給子組件加上xxx-exitxxx-exit-activeclass,然后開始執(zhí)行動(dòng)畫,當(dāng)動(dòng)畫結(jié)束后,移除兩個(gè)class,然后添加-enter-doneclass

如下例子:

export default class App2 extends React.PureComponent {
  state = {show: true};
  onToggle = () => this.setState({show: !this.state.show});
  render() {
    const {show} = this.state;
    return (
      <div className={'container'}>
        <div className={'square-wrapper'}>
          <CSSTransition
            in={show}
            timeout={500}
            classNames={'fade'}
            unmountOnExit={true}
          >
            <div className={'square'} />
          </CSSTransition>
        </div>
        <Button onClick={this.onToggle}>toggle</Button>
      </div>
    );
  }
}

對(duì)應(yīng)css樣式如下:

.fade-enter {
  opacity: 0;
  transform: translateX(100%);
}
.fade-enter-active {
  opacity: 1;
  transform: translateX(0);
  transition: all 500ms;
}
.fade-exit {
  opacity: 1;
  transform: translateX(0);
}
.fade-exit-active {
  opacity: 0;
  transform: translateX(-100%);
  transition: all 500ms;
}

SwitchTransition

SwitchTransition可以完成兩個(gè)組件之間切換的炫酷動(dòng)畫

比如有一個(gè)按鈕需要在onoff之間切換,我們希望看到on先從左側(cè)退出,off再?gòu)挠覀?cè)進(jìn)入

SwitchTransition中主要有一個(gè)屬性mode,對(duì)應(yīng)兩個(gè)值:

  • in-out:表示新組件先進(jìn)入,舊組件再移除;
  • out-in:表示就組件先移除,新組建再進(jìn)入

SwitchTransition組件里面要有CSSTransition,不能直接包裹你想要切換的組件

里面的CSSTransition組件不再像以前那樣接受in屬性來判斷元素是何種狀態(tài),取而代之的是key屬性

下面給出一個(gè)按鈕入場(chǎng)和出場(chǎng)的示例,如下:

import { SwitchTransition, CSSTransition } from "react-transition-group";
export default class SwitchAnimation extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      isOn: true
    }
  }
  render() {
    const {isOn} = this.state;
    return (
      <SwitchTransition mode="out-in">
        <CSSTransition classNames="btn"
                       timeout={500}
                       key={isOn ? "on" : "off"}>
          {
          <button onClick={this.btnClick.bind(this)}>
            {isOn ? "on": "off"}
          </button>
        }
        </CSSTransition>
      </SwitchTransition>
    )
  }
  btnClick() {
    this.setState({isOn: !this.state.isOn})
  }
}

css文件對(duì)應(yīng)如下:

.btn-enter {
  transform: translate(100%, 0);
  opacity: 0;
}
.btn-enter-active {
  transform: translate(0, 0);
  opacity: 1;
  transition: all 500ms;
}
.btn-exit {
  transform: translate(0, 0);
  opacity: 1;
}
.btn-exit-active {
  transform: translate(-100%, 0);
  opacity: 0;
  transition: all 500ms;
}

TransitionGroup

當(dāng)有一組動(dòng)畫的時(shí)候,就可將這些CSSTransition放入到一個(gè)TransitionGroup中來完成動(dòng)畫

同樣CSSTransition里面沒有in屬性,用到了key屬性

TransitionGroup在感知children發(fā)生變化的時(shí)候,先保存移除的節(jié)點(diǎn),當(dāng)動(dòng)畫結(jié)束后才真正移除

其處理方式如下:

  • 插入的節(jié)點(diǎn),先渲染dom,然后再做動(dòng)畫
  • 刪除的節(jié)點(diǎn),先做動(dòng)畫,然后再刪除dom

如下:

import React, { PureComponent } from 'react'
import { CSSTransition, TransitionGroup } from 'react-transition-group';
export default class GroupAnimation extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      friends: []
    }
  }
  render() {
    return (
      <div>
        <TransitionGroup>
          {
            this.state.friends.map((item, index) => {
              return (
                <CSSTransition classNames="friend" timeout={300} key={index}>
                  <div>{item}</div>
                </CSSTransition>
              )
            })
          }
        </TransitionGroup>
        <button onClick={e => this.addFriend()}>+friend</button>
      </div>
    )
  }
  addFriend() {
    this.setState({
      friends: [...this.state.friends, "coderwhy"]
    })
  }
}

對(duì)應(yīng)css如下:

.friend-enter {
    transform: translate(100%, 0);
    opacity: 0;
}
.friend-enter-active {
    transform: translate(0, 0);
    opacity: 1;
    transition: all 500ms;
}
.friend-exit {
    transform: translate(0, 0);
    opacity: 1;
}
.friend-exit-active {
    transform: translate(-100%, 0);
    opacity: 0;
    transition: all 500ms;
}

原文鏈接:https://juejin.cn/post/7140641440656261133

欄目分類
最近更新