React動畫

1. React過渡動畫

  • 在React中我們可以通過原生的CSS來實現(xiàn)過渡動畫,
    但是React社區(qū)為我們提供了react-transition-group幫助我們快速過渡動畫

2. 動畫組件:

  • Transition
    • 該組件是一個和平臺無關(guān)的組件(不一定要結(jié)合CSS);
    • 在前端開發(fā)中,我們一般是結(jié)合CSS來完成樣式,所以比較常用的是CSSTransition;
  • CSSTransition
    • 在前端開發(fā)中,通常使用CSSTransition來完成過渡動畫效果
  • SwitchTransition
    • 兩個組件顯示和隱藏切換時,使用該組件
  • TransitionGroup
    • 將多個動畫組件包裹在其中,一般用于列表中元素的動畫;
1.1 原生CSS實現(xiàn)動畫

原生CSS一般是通過state轉(zhuǎn)換為props再結(jié)合style-conponents以及邏輯完成動畫

const StyleDiv  = styled.div`
  width: ${props => props.width};
  height: ${props => props.height};
  background: skyblue;
  opacity: ${props => props.opacity};
  transition: all 3s;
`
class App extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            width: 0,
            height: 0,
            opacity:0
        }
    }
    render(){
        return (
            <div>
                <StyleDiv {...this.state}></StyleDiv>
                <button onClick={()=>{this.btnClick()}}>按鈕</button>
            </div>
        );
    }
    btnClick(){
        this.setState({
            width: '100px',
            height: '100px',
            opacity:1
        })
    }
}
export default App;
1.2 CSSTransition容器組件

在前端開發(fā)中,通常使用CSSTransition來完成過渡動畫效果

  1. 如何通過CSSTransition來實現(xiàn)過渡效果?
    1.1 安裝react-transition-group
    npm install react-transition-group --save
    1.2 從安裝好的庫中導入CSSTransition
    import {CSSTransition} from 'react-transition-group';
    1.3利用CSSTransition將需要執(zhí)行過渡效果的組件或元素包裹起來
    1.4 編寫對應的CSS動畫
    實現(xiàn): .-enter/ .-enter-active / .-enter-done/.-exit/ .-exit-active / .-exit-done
    1.5給CSSTransition添加一些屬性
    in屬性 :
    取值是一個布爾值, 如果取值為false表示觸發(fā)退出動畫, 如果取值是true表示觸發(fā)進入動畫
    classNames屬性:
    指定動畫類名的前綴
    timeout屬性 :
    設(shè)置動畫超時時間

3.CSSTransition狀態(tài)

  • CSSTransition有三個狀態(tài):
    • appear: 初始
    • enter : 進入
    • exit;: 退出
  • 當組件第一次加載時候會自動查找
    -appear / -appear-active / -appear-done
  • 當組件顯示時會自動查找
    -enter / -enter-active / -enter-done
  • 當組件退出時會自動查找
    -exit / -exit-active / -exit-done
    4.unmountOnExit:
    unmountOnExit如果取值為true, 那么表示退出動畫執(zhí)行完畢之后刪除對應的元素
import React from 'react';
import './App.css'
import {CSSTransition} from 'react-transition-group';
class App extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            isShow: false
        }
    }
    render(){
        return (
            <div>
                <CSSTransition in={this.state.isShow}
                                classNames={'box'}
                                timeout={3000}
                                appear
                                unmountOnExit={true}>
                    <div></div>
                </CSSTransition>
                <button onClick={()=>{this.btnClick()}}>顯示</button>
            </div>
        );
    }
    btnClick(){
        this.setState({
            isShow: true
        })
    }
}
export default App;
.box-enter{
    /*進入動畫執(zhí)行之前綁定的類名*/
    width: 0;
    height: 0;
    opacity: 0;
    background: skyblue;
}
.box-enter-active{
    /*進入動畫執(zhí)行過程中綁定的類名*/
    width: 100px;
    height: 100px;
    opacity: 1;
    transition: all 3s;
}
.box-enter-done{
    /*進入動畫執(zhí)行完畢之后綁定的類名*/
    width: 100px;
    height: 100px;
    opacity: 1;
    background: red;
}
.box-exit{
    /*退出動畫執(zhí)行之前綁定的類名*/
    width: 100px;
    height: 100px;
    opacity: 1;
    background: red;
}
.box-exit-active{
    /*退出動畫執(zhí)行過程中綁定的類名*/
    width: 0;
    height: 0;
    opacity: 0;
    transition: all 3s;
}
.box-exit-done{
    /*退出動畫執(zhí)行完畢之后綁定的類名*/
    width: 0;
    height: 0;
    opacity: 0;
    background: skyblue;
}
.box{
    width: 100px;
    height: 100px;
    background: skyblue;
}

.box-appear{
    /*初始化動畫執(zhí)行之前綁定的類名*/
    width: 0;
    height: 0;
    opacity: 0;
    background: skyblue;
}
.box-appear-active{
    /*初始化動畫執(zhí)行過程中綁定的類名*/
    width: 100px;
    height: 100px;
    opacity: 1;
    transition: all 3s;
}
.box-appear-done{
    /*初始化動畫執(zhí)行完畢之后綁定的類名*/
    width: 100px;
    height: 100px;
    opacity: 1;
    background: red;
}
2. transition 回調(diào)函數(shù)
  • 生命周期方法
    • onEnter/onEntering/onEntered
    • onExit/onExiting/onExited
import React from 'react';
import './App.css'
import {CSSTransition} from 'react-transition-group';
class App extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            isShow: true
        }
    }
    render(){
        return (
            <div>
                <CSSTransition in={this.state.isShow}
                                classNames={'box'}
                                timeout={3000}
                                unmountOnExit={true}
                                appear
                                onEnter = {this.myFn}
                               onEntering={()=>{console.log('進入動畫執(zhí)行過程中');}}
                               onEntered={()=>{console.log('進入動畫執(zhí)行完畢');}}
                >
                    <div className={'box'}></div>
                </CSSTransition>
                <button onClick={()=>{this.btnClick1()}}>顯示</button>
                <button onClick={()=>{this.btnClick2()}}>隱藏</button>
            </div>
        );
    }
    myFn(currentEl, isAppear){
        // console.log(currentEl, isAppear);
        console.log('進入動畫開始之前');
    }
    btnClick1(){
        this.setState({
            isShow: true
        })
    }
    btnClick2(){
        this.setState({
            isShow: false
        })
    }
}
export default App;
image.png
3. Transition
  1. SwitchTransition
  • SwitchTransition可以完成組件切換的動畫
  • SwitchTransition組件里面要有CSSTransition或者Transition組件,不能直接包裹你想要切換的組件
  • SwitchTransition里面的CSSTransition或Transition組件不再像以前那樣接受in屬性來判斷元素是何種狀態(tài), 取而代之的是key屬性
import React from 'react';
import './App.css'
import {CSSTransition, SwitchTransition} from 'react-transition-group';
class App extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            isOn: true
        }
    }
    render(){
        return (
            <div>
                <SwitchTransition mode={'in-out'}>
                    <CSSTransition key={this.state.isOn}
                                   timeout={3000}
                                    classNames={'btn'}>
                        <button onClick={()=>{this.setState({isOn: !this.state.isOn})}}>{this.state.isOn ? 'on' : 'off'}</button>
                    </CSSTransition>
                </SwitchTransition>
            </div>
        );
    }
}
export default App;
import React from 'react';
import './App.css'
import {CSSTransition, TransitionGroup} from 'react-transition-group';

class App extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            // heroList : ['魯班', '魯班', '魯班']
            heroList:[
                {id:1, name:'魯班'},
                {id:2, name:'虞姬'},
                {id:3, name:'黃忠'},
            ]
        }
    }
    render(){
        return (
            <div>
                <ul>
                    <TransitionGroup>
                    {
                        /*
                        注意點:
                        在企業(yè)開發(fā)中一定要保證CSSTransition key的唯一性
                        * */
                        this.state.heroList.map((obj, index) =>{
                            return (
                                <CSSTransition key={obj.id}
                                               timeout={3000}
                                               classNames={'item'}>
                                    <li onClick={()=>{this.removeHero(index)}}>{obj.name}</li>
                                </CSSTransition>
                            )
                        })
                    }
                    </TransitionGroup>
                </ul>
                <button onClick={()=>{this.btnClick()}}>新增</button>
            </div>
        );
    }
    btnClick(){
        this.setState({
            // heroList: [...this.state.heroList, '阿珂']
            heroList: [...this.state.heroList, {id: this.state.heroList.length + 1, name:'阿珂'}]
        })
    }
    removeHero(index){
        // console.log(index);
        const list = this.state.heroList.filter((name, idx) =>{
            return idx !== index;
        })
        // console.log(list);
        this.setState({
            heroList: list
        })
    }
}
export default App;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容