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

學無先后,達者為師

網站首頁 編程語言 正文

react組件中過渡動畫的問題解決_React

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

一、是什么

在日常開發中,頁面切換時的轉場動畫是比較基礎的一個場景

當一個組件在顯示與消失過程中存在過渡動畫,可以很好的增加用戶的體驗

react中實現過渡動畫效果會有很多種選擇,如react-transition-groupreact-motionAnimated,以及原生的CSS都能完成切換動畫

二、如何實現

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

可以幫助我們方便的實現組件的入場和離場動畫

其主要提供了三個主要的組件:

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

CSSTransition

其實現動畫的原理在于,當CSSTransitionin屬性置為true時,CSSTransition首先會給其子組件加上xxx-enterxxx-enter-activeclass執行動畫

當動畫執行結束后,會移除兩個class,并且添加-enter-doneclass

所以可以利用這一點,通過csstransition屬性,讓元素在兩個狀態之間平滑過渡,從而得到相應的動畫效果

in屬性置為false時,CSSTransition會給子組件加上xxx-exitxxx-exit-activeclass,然后開始執行動畫,當動畫結束后,移除兩個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>
    );
  }
}

對應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可以完成兩個組件之間切換的炫酷動畫

比如有一個按鈕需要在onoff之間切換,我們希望看到on先從左側退出,off再從右側進入

SwitchTransition中主要有一個屬性mode,對應兩個值:

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

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

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

下面給出一個按鈕入場和出場的示例,如下:

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文件對應如下:

.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

當有一組動畫的時候,就可將這些CSSTransition放入到一個TransitionGroup中來完成動畫

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

TransitionGroup在感知children發生變化的時候,先保存移除的節點,當動畫結束后才真正移除

其處理方式如下:

  • 插入的節點,先渲染dom,然后再做動畫
  • 刪除的節點,先做動畫,然后再刪除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"]
    })
  }
}

對應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

欄目分類
最近更新