React入門指南(學習筆記)

只會番茄炒蛋發表於2019-09-05

React簡介

首先不能否認React.js是全球最火的前端框架(Facebook推出的前端框架),國內的一二線網際網路公司大部分都在使用React進行開發,比如阿里、美團、百度、去哪兒、網易 、知乎這樣的一線網際網路公司都把React作為前端主要技術棧。

React的社群也是非常強大的,隨著React的普及也衍生出了更多有用的框架,比如ReactNative和React VR。React從13年開始推廣,現在已經推出16RC(React Fiber)這個版本,效能和易用度上,都有很大的提升。

React優點總結

  • 生態強大:現在沒有哪個框架比React的生態體系好的,幾乎所有開發需求都有成熟的解決方案。
  • 上手簡單: 你甚至可以在幾個小時內就可以上手React技術,但是他的知識很廣,你可能需要更多的時間來完全駕馭它。
  • 社群強大:你可以很容易的找到志同道合的人一起學習,因為使用它的人真的是太多了。

需要的前置知識

  • JavaScript基礎:如果能會ES6就更好了

  • npm基礎:你需要會使用npm的包管理


React開發環境搭建

  • 安裝Node只需要進入Node網站,進行響應版本的下載,然後進行雙擊安裝就可以了。
// 安裝完成開啟命令視窗輸入
node -v   //出現版本號則安裝成功
複製程式碼
  • 腳手架的安裝
// 安裝react的腳手架工具
//create-react-app是React官方出的腳手架工具
npm install -g create-react-app  
複製程式碼
  • 建立一個React專案
// 桌面建立一個react-demo的資料夾
// 進入當前資料夾,開啟命令列
create-react-app demo   //用腳手架建立React專案
npm start   // 安裝完成進入demo資料夾啟動專案
複製程式碼

專案根目錄中的檔案介紹

  • README.md :這個檔案主要作用就是對專案的說明,已經預設寫好了一些東西,你可以簡單看看。如果是工作中,你可以把檔案中的內容刪除,自己來寫這個檔案,編寫這個檔案可以使用Markdown的語法來編寫。

  • package.json: 這個檔案是webpack配置和專案包管理檔案,專案中依賴的第三方包(包的版本)和一些常用命令配置都在這個裡邊進行配置,當然腳手架已經為我們配置了一些了,目前位置,我們不需要改動。如果你對webpack瞭解,對這個一定也很熟悉。

  • package-lock.json:這個檔案用一句話來解釋,就是鎖定安裝時的版本號,並且需要上傳到git,以保證其他人再npm install 時大家的依賴能保證一致。

  • gitignore: 這個是git的選擇性上傳的配置檔案,比如一會要介紹的node_modules資料夾,就需要配置不上傳。

  • node_modules:這個資料夾就是我們專案的依賴包,到目前位置,腳手架已經都給我們下載好了,你不需要單獨安裝什麼。

  • public:公共檔案,裡邊有公用模板和圖示等一些東西。

  • src: 主要程式碼編寫檔案,這個資料夾裡的檔案對我們來說最重要,都需要我們掌握。

public資料夾介紹

這個檔案都是一些專案使用的公共檔案,也就是說都是共用的

  • favicon.ico: 這個是網站或者說專案的圖示,一般在瀏覽器標籤頁的左上角顯示。

  • index.html: 首頁的模板檔案

  • mainifest.json:移動端配置檔案

src資料夾介紹

這個目錄裡邊放的是我們開放的原始碼,我們平時操作做最多的目錄。

  • index.js: 這個就是專案的入口檔案

  • index.css:這個是index.js裡的CSS檔案。

  • app.js: 這個檔案相當於一個方法模組,也是一個簡單的模組化程式設計。

  • serviceWorker.js:這個是用於寫移動端開發的,PWA必須用到這個檔案,有了這個檔案,就相當於有了離線瀏覽的功能。


元件的介紹

入口檔案的編寫

寫一個專案的時候一般要從入口檔案進行編寫的,在src目錄下,index.js檔案就是入口檔案

import React from 'react' // 引入react
import ReactDOM from 'react-dom' // 引入react-dom
import App from './App' // 引入App模組
ReactDOM.render(<App />,document.getElementById('root')) // 將App模組渲染到了 root ID上面
複製程式碼

App元件的編寫

import React from 'react'
// JSX語法
class App extends React.Component{
    render(){
        return (
            <div>
                我是APP元件
            </div>
        )
    }
}
export default App;
複製程式碼

React中JSX語法簡介

JSX就是Javascript和XML結合的一種格式。React發明了JSX,
可以方便的利用HTML語法來建立虛擬DOM,當遇到<,JSX就當作HTML解析,
遇到{就當JavaScript解析.
複製程式碼

元件和普通JSX語法區別

這個說起來也只有簡單的一句話,就是你自定義的元件必須首寫字母要進行大寫,而JSX是小寫字母開頭的。

JSX中使用三元運算子

在JSX中也是可以使用js語法的

import React from 'react'
// JSX語法
class App extends React.Component{
    render(){
        return (
            <div>
                <div>{false ? '不顯示我' : '顯示的我'}</div>
                我是APP元件
            </div>
        )
    }
}
export default App;
複製程式碼

元件外層包裹原則

react和vue元件模板的原則一樣,最外層必須有且只有一個元素,多了會報錯

下面這個列子就是一個錯誤的,因為最外層有了兩個元素

import React from 'react'
// JSX語法
class App extends React.Component{
    render(){
        return (
            <div></div>
            <div>
                <div>{false ? '不顯示我' : '顯示的我'}</div>
                我是APP元件
            </div>
        )
    }
}
export default App;
複製程式碼

Fragment標籤

加上最外層的DIV,元件就是完全正常的,但是你的佈局就偏不需要這個最外層的標籤怎麼辦?比如我們在作Flex佈局的時候,外層還真的不能有包裹元素。這種矛盾其實React16已經有所考慮了,為我們準備了標籤。

import React from 'react'
// JSX語法
class App extends React.Component{
    render(){
        return (
            <React.Fragment>
                <div>{false ? '不顯示我' : '顯示的我'}</div>
            </React.Fragment>
        )
    }
}
export default App;
複製程式碼

這時候再去瀏覽器的Elements中檢視,就會發現已經沒有外層的包裹了。


響應式設計和資料的繫結

React不建議你直接操作DOM元素,而是要通過資料進行驅動,改變介面中的效果。React會根據資料的變化,自動的幫助你完成介面的改變。所以在寫React程式碼時,你無需關注DOM相關的操作,只需要關注資料的操作就可以了(這也是React如此受歡迎的主要原因,大大加快了我們的開發速度)。

import React from 'react'
// JSX語法
class App extends React.Component{
    constructor(props){
    super(props) //呼叫父類的建構函式,固定寫法
        this.state={
            myName: '只會番茄炒蛋',
            list: ['番茄', '炒蛋']
        }
    }
    render(){
        return (
            <React.Fragment>
                <div>{this.state.myName}</div>
                <ul>
                    {
                        this.state.list.map((item,index) => {
                            return (
                                <li key={item + index}>{item}</li>
                            )
                        })
                    }
                </ul>
            </React.Fragment>
        )
    }
}
export default App;
複製程式碼

繫結事件

import React from 'react'
// JSX語法
class App extends React.Component{
    constructor(props){
    super(props) //呼叫父類的建構函式,固定寫法
        this.state={
            myName: '只會番茄炒蛋',
            list: ['番茄', '炒蛋']
        }
        this.changeBtn = this.changeBtn.bind(this)
    }
    render(){
        return (
            <React.Fragment>
                <div>{this.state.myName}</div>
                <button onClick={this.changeBtn}>點選事件</button>
            </React.Fragment>
        )
    }
    changeBtn () {
        // 這裡要注意,如果沒有繫結this這裡的this是undefined
        // 通過setState方法去改變資料,保證頁面會渲染改變後的內容
        this.setState({
            myName: '我的點選按鈕後被改變的值'
        })
    }
}
export default App;
複製程式碼

JSX防踩坑的幾個地方

JSX程式碼註釋

以下兩種方式書寫程式碼註釋

 {/* 正確註釋的寫法 */}
 { // 正確註釋的寫法 }
複製程式碼

JSX中的class陷阱

它是防止和js中的class類名衝突, 所以JSX中都是用className

<input class="input"/>  // 錯誤的寫法
<input className="input"/>  // 正確的寫法
複製程式碼

JSX中的html解析問題

如果想在文字框裡輸入一個h1標籤,並進行渲染。預設是不會生效的,只會把h1標籤列印到頁面上,這並不是我想要的。如果工作中有這種需求,可以使用dangerouslySetInnerHTML屬性解決。具體程式碼如下:

<li dangerouslySetInnerHTML={{__html:item}}> {<h1>我會變成h1號字型</h1>}</li>
複製程式碼

JSX中

JSX中label的坑,也算是比較大的一個坑,label是html中的一個輔助標籤,也是非常有用的一個標籤。

<div>
    <label>加入服務:</label>
    <input className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
    <button onClick={this.addList.bind(this)}> 增加服務 </button>
</div>
複製程式碼

這時候想點選“加入服務”直接可以啟用文字框,方便輸入。按照html的原思想,是直接加ID就可以了。程式碼如下:

<div>
    <label for="jspang">加入服務:</label>
    <input id="jspang" className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
    <button onClick={this.addList.bind(this)}> 增加服務 </button>
</div>
複製程式碼

這時候你瀏覽效果雖然可以正常,但console裡還是有紅色警告提示的。大概意思是不能使用for.它容易和javascript裡的for迴圈混淆,會提示你使用htmlfor。

<div>
    <label htmlFor="jspang">加入服務:</label>
    <input id="jspang" className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
    <button onClick={this.addList.bind(this)}> 增加服務 </button>
</div>
複製程式碼

元件的拆分

父元件如何使用子元件

// 子元件
import React from 'react'
// JSX語法
class childItem extends React.Component{
    return (
        <React.Fragment>
            <div>我是子元件</div>
        </React.Fragment>
    )
}
export default childItem;
複製程式碼
// 父元件
import React from 'react'
// 引入子元件
import childItem from './childItem'
// JSX語法
class parentItem extends React.Component{
    return (
        <React.Fragment>
            {/* 使用了子元件 */}
            <childItem/>
        </React.Fragment>
    )
}
export default parentItem;
複製程式碼

父子元件的傳值

父元件通過自定義屬性將要傳遞的值傳遞給子元件

// 父元件
import React from 'react'
// 引入子元件
import childItem from './childItem'
// JSX語法
class parentItem extends React.Component{
    constractor (props) {
        super(props)
        this.state = {
            myName: '只會番茄炒蛋'
        }
    }
    return (
        <React.Fragment>
            {/* 使用了子元件 */}
            <childItem myName={this.state.myName}/>
        </React.Fragment>
    )
}
export default parentItem;
複製程式碼

子元件通過this.props.XXX接受父元件傳遞迴來的值

// 子元件
import React from 'react'
// JSX語法
class childItem extends React.Component{
    return (
        <React.Fragment>
            <div>{this.props.myName}</div>
        </React.Fragment>
    )
}
export default childItem;
複製程式碼

父元件向子元件傳遞內容,靠屬性的形式傳遞。

子元件向父元件傳遞資料

切記單項資料流!!!

React有明確規定,子元件時不能操作父元件裡的資料的,所以需要藉助一個父元件的方法,來修改父元件的內容。

// 子元件
import React from 'react'
// JSX語法
class childItem extends React.Component{
    constructor (props) {
        super(props)
        this.changeParent = this.changeParent.bind(this)
    }
    return (
        <React.Fragment>
            <div onClick={this.changeParent}>{this.props.myName}</div>
        </React.Fragment>
    )
    changeParent () {
        // 呼叫父元件傳遞過來的方法
        this.props.pranentChange()
    }
}
export default childItem;
複製程式碼
// 父元件
import React from 'react'
// 引入子元件
import childItem from './childItem'
// JSX語法
class parentItem extends React.Component{
    constractor (props) {
        super(props)
        this.state = {
            myName: '只會番茄炒蛋'
        }
        this.pranentChange = this.pranentChange.bind(this)
    }
    return (
        <React.Fragment>
            {/* 使用了子元件 */}
            <childItem 
                pranentChange={this.pranentChange}
                myName={this.state.myName}
            />
        </React.Fragment>
    )
    pranentChange () {
        this.setState({
            myName: '番茄炒蛋少放糖'
        })
    }
}
export default parentItem;
複製程式碼

PropTypes校驗傳遞值

在父元件向子元件傳遞資料時,使用了屬性的方式,也就是props,但是沒有任何的限制。這在工作中時完全不允許的,因為大型專案,如果你不校驗,後期會變的異常混亂,業務邏輯也沒辦法保證。

PropTypes的應用

普通效驗

// 子元件
import React from 'react'
// 引入效驗
import PropTypes from 'prop-types'
// JSX語法
class childItem extends React.Component{
    constructor (props) {
        super(props)
        this.changeParent = this.changeParent.bind(this)
    }
    return (
        <React.Fragment>
            <div onClick={this.changeParent}>{this.props.myName}</div>
        </React.Fragment>
    )
    changeParent () {
        // 呼叫父元件傳遞過來的方法
        this.props.pranentChange()
    }
}
childItem.prorTypes = {
    myName: PropTypes.string, // 效驗傳入的內容必須是一個字串
    pranentChange: PropTypes.func // 效驗傳入的內容必須是一個function
}
export default childItem;
複製程式碼

注意: 這裡新增效驗以後,如果不按照效驗規則傳入內容會有warning警告

必傳值的效驗---isRequired

例如這裡加了一個newName的屬性,並且放入JSX中,就算父元件不傳遞這個值也不會報錯的

// 子元件
render() { 
    return ( 
        <div >{this.props.newName}</div>
    );
}
複製程式碼

但是怎樣避免必須傳遞newName這個屬性值?如果不傳遞就報錯,這就需要使用isRequired關鍵字了,它表示必須進行傳遞,如果不傳遞就報錯。

childItem.prorTypes = {
    // 效驗傳入的內容必須是一個字串並且必須傳入值
    newName:PropTypes.string.isRequired, 
}
複製程式碼

使用預設值---defaultProps

有時候子元件是需要有一個預設的值,如果父元件不傳就用預設的,如果傳了就用父元件傳遞過來的值,defalutProps就可以實現預設值的功能,比如現在把newName的預設值設定成"只會番茄炒蛋" 。

childItem.defaultProps = {
    // 子元件使用父元件傳遞的值,但是他自己有個預設的值
    newName:'只會番茄炒蛋'
}
複製程式碼

ref的使用方法

在編寫元件中的方法時,經常會遇到語義化很模糊的程式碼,這對於團隊開發是一個很大的問題。因為review程式碼或者合作時都會影響開發效率。或者到這核心成員離開,專案倒閉的嚴重影響。所以我們必須重視react程式碼當中的語義化。ref是個不錯的工具

import React from 'react'
// JSX語法
class parentItem extends React.Component{
    constractor (props) {
        super(props)
        this.state = {
            myName: '只會番茄炒蛋'
        }
        this.inputChange = this.inputChange.bind(this)
    }
    return (
        <React.Fragment>
            <input 
                value={this.state.myName}
                onChange={this.inputChange}
            ></input>
        </React.Fragment>
    )
    inputChange (e) {
        console.log(e.target.value)
    }
}
export default parentItem;
複製程式碼

想要獲取上面input輸入的值,必須通過e.target.value,這樣並不直觀,也不好看,這中情況可以使用ref來進行解決

import React from 'react'
// JSX語法
class parentItem extends React.Component{
    constractor (props) {
        super(props)
        this.state = {
            myName: '只會番茄炒蛋'
        }
        this.inputChange = this.inputChange.bind(this)
    }
    return (
        <React.Fragment>
            <input 
                value={this.state.myName}
                onChange={this.inputChange}
                ref={input => {this.input = input}}
            ></input>
        </React.Fragment>
    )
    inputChange (e) {
        console.log(this.input.value)
    }
}
export default parentItem;
複製程式碼

這就使程式碼變得語義化和優雅的多。但是是不建議用ref這樣操作的,因為React的是資料驅動的,所以用ref會出現各種問題。

ref使用中的坑

比如現在我們要用ref繫結獲取子元素的數量,可以先用ref進行繫結。

<ul ref={(ul)=>{this.ul=ul}}>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>  
複製程式碼

這時候如果我們動態新增或者減少li的數量,並在方法中列印li的數量,發現返回的數量並不準確,這個坑是因為React中更新setState是一個非同步函式所造成的。也就是這個setState在程式碼執行是有一個時間的,如果你真的想了解清楚,你需要對什麼是虛擬DOM有一個瞭解。簡單的說,就是因為是非同步,還沒等虛擬Dom渲染,我們的console.log就已經執行了。

那這個程式碼怎麼編寫才會完全正常那,其實setState方法提供了一個回撥函式,也就是它的第二個函式。下面這樣寫就可以實現我們想要的方法了。

增加/刪除(){
    this.setState({
        list:改變後的資料,
    },()=>{
        console.log(this.ul.querySelectorAll('li').length)
    })
}
複製程式碼

生命週期

React入門指南(學習筆記)

什麼是生命週期函式

生命週期函式指在某一個時刻元件會自動呼叫執行的函式
複製程式碼

掛載

當元件例項被建立並插入 DOM 中時,其生命週期呼叫順序如下:

  • constructor()
如果不初始化 state 或不進行方法繫結,則不需要為 React 元件實現建構函式。
在 React 元件掛載之前,會呼叫它的建構函式。在為 React.Component 子類實現建構函式時,
應在其他語句之前前呼叫 super(props)。否則,this.props 在建構函式中可能會出現未定義的 bug。

通常,在 React 中,建構函式僅用於以下兩種情況:
* 通過給 this.state 賦值物件來初始化內部 state。
* 為事件處理函式繫結例項

在 constructor() 函式中不要呼叫 setState() 方法。
如果你的元件需要使用內部 state,請直接在建構函式中為 this.state 賦值初始 state:
複製程式碼
  • static getDerivedStateFromProps()
getDerivedStateFromProps 會在呼叫 render 方法之前呼叫,並且在初始掛載及後續更新時都會被呼叫。
它應返回一個物件來更新 state,如果返回 null 則不更新任何內容。
複製程式碼
  • render()
頁面state或props發生變化時執行。
複製程式碼
  • componentDidMount()
元件掛載完成時被執行。一般也在這裡發起網路請求
複製程式碼

更新

當元件的 props 或 state 發生變化時會觸發更新。元件更新的生命週期呼叫順序如下:

  • static getDerivedStateFromProps()
// 不常用的生命週期方法
getDerivedStateFromProps 會在呼叫 render 方法之前呼叫,並且在初始掛載及後續更新時都會被呼叫。
它應返回一個物件來更新 state,如果返回 null 則不更新任何內容。
複製程式碼
  • shouldComponentUpdate()
// 不常用的生命週期方法
根據 shouldComponentUpdate() 的返回值,判斷 React 元件的輸出是否受當前 state 或 props 更改的影響。
預設行為是 state 每次發生變化元件都會重新渲染。大部分情況下,你應該遵循預設行為。
複製程式碼
  • render()
render() 方法是 class 元件中唯一必須實現的方法。
當 render 被呼叫時,它會檢查 this.props 和 this.state 的變化
複製程式碼
  • getSnapshotBeforeUpdate()
// 不常用的生命週期方法
getDerivedStateFromProps 會在呼叫 render 方法之前呼叫,並且在初始掛載及後續更新時都會被呼叫。
它應返回一個物件來更新 state,如果返回 null 則不更新任何內容。
複製程式碼
  • componentDidUpdate()
componentDidUpdate() 會在更新後會被立即呼叫。首次渲染不會執行此方法。
複製程式碼

解除安裝

當元件從 DOM 中移除時會呼叫如下方法:

  • componentWillUnmount()
componentWillUnmount() 會在元件解除安裝及銷燬之前直接呼叫。在此方法中執行必要的清理操作,
例如,清除 timer,取消網路請求或清除在 componentDidMount() 中建立的訂閱等。
複製程式碼

錯誤處理

當渲染過程,生命週期,或子元件的建構函式中丟擲錯誤時,會呼叫如下方法:

  • static getDerivedStateFromError()
// 不常用的生命週期方法
此生命週期會在後代元件丟擲錯誤後被呼叫。 它將丟擲的錯誤作為引數,並返回一個值以更新 state
複製程式碼
  • componentDidCatch()
// 不常用的生命週期方法
componentDidCatch() 會在“提交”階段被呼叫,因此允許執行副作用。 它應該用於記錄錯誤之類的情況:
複製程式碼

React中的axios資料請求

安裝axios

npm install  axios -S
複製程式碼

使用

// 那個元件使用在那個頁面引入
import axios from 'axios'
複製程式碼

引入後,可以在componentDidMount生命週期函式裡請求ajax,我也建議在componentDidMount函式裡執行,因為在render裡執行,會出現很多問題,比如一直迴圈渲染;在componentWillMount裡執行,在使用RN時,又會有衝突。所以強烈建議在componentDidMount函式裡作ajax請求。

componentDidMount(){
    axios.post('https://www.easy-mock.com/mock/5d50245e710c4d0d04d78d19/echart')
        .then((res)=>{console.log('axios 獲取資料成功:'+JSON.stringify(res))  })
        .catch((error)=>{console.log('axios 獲取資料失敗'+error)})
}
複製程式碼

動畫react-transition-group

React有著極好的開發生態,開發需要的任何基本需求都可以找到官方或大神造的輪子,動畫這種必不可少的東西當然也不例外,React生態中有很多第三方的動畫元件,學習一下react-transition-group動畫元件。可以滿足日常動畫開發需求。 推薦的最重要理由是:這個也是react官方提供的動畫過渡庫,有著完善的API文件)。

安裝react-transition-group

npm install react-transition-group -S
複製程式碼

安裝好後,你可以先去github上來看一下文件,他是有著三個核心庫(或者叫元件)。

  • Transition
  • CSSTransition
  • TransitionGroup

使用CSSTransition

先用import進行引入,程式碼如下:

import { CSSTransition } from 'react-transition-group'
複製程式碼

引入後便可以使用了,使用的方法就和使用自定義元件一樣,直接寫,而且不再需要管理className了,這部分由CSSTransition進行管理。

render() { 
    return ( 
        <div>
            <CSSTransition 
                in={this.state.isShow}   //用於判斷是否出現的狀態
                timeout={2000}           //動畫持續時間
                classNames="boss-text"   //className值,防止重複
            >
                <div>BOSS級人物-孫悟空</div>
            </CSSTransition>
            <div><button onClick={this.toToggole}>召喚Boss</button></div>
        </div>
        );
}
複製程式碼

需要注意的是classNames這個屬性是由s的,如果你忘記寫,會和原來的ClassName混淆出錯,這個一定要注意。

  • xxx-enter: 進入(入場)前的CSS樣式;
  • xxx-enter-active:進入動畫直到完成時之前的CSS樣式;
  • xxx-enter-done:進入完成時的CSS樣式;
  • xxx-exit:退出(出場)前的CSS樣式;
  • xxx-exit-active:退出動畫知道完成時之前的的CSS樣式。
  • xxx-exit-done:退出完成時的CSS樣式。
.input {border:3px solid #ae7000}

.boss-text-enter{
    opacity: 0;
}
.boss-text-enter-active{
    opacity: 1;
    transition: opacity 2000ms;

}
.boss-text-enter-done{
    opacity: 1;
}
.boss-text-exit{
    opacity: 1;
}
.boss-text-exit-active{
    opacity: 0;
    transition: opacity 2000ms;

}
.boss-text-exit-done{
    opacity: 0;
}
複製程式碼
unmountOnExit 屬性

CSSTransition加上unmountOnExit屬性,加上這個的意思是在元素退場時,自動把DOM也刪除,這是以前用CSS動畫沒辦法做到的。

render() { 
    return ( 
        <div>
            <CSSTransition 
                in={this.state.isShow}   //用於判斷是否出現的狀態
                timeout={2000}           //動畫持續時間
                classNames="boss-text"   //className值,防止重複
                unmountOnExit
            >
                <div>BOSS級人物-孫悟空</div>
            </CSSTransition>
            <div><button onClick={this.toToggole}>召喚Boss</button></div>
        </div>
        );
}
複製程式碼

使用TransitionGroup

它就是負責多個DOM元素的動畫的,我們還是拿小姐姐這個案例作例子,現在可以新增任何的服務專案,但是都是直接出現的,沒有任何動畫,現在就給它新增上動畫。新增動畫,先引入transitionGrop。

import {CSSTransition , TransitionGroup} from 'react-transition-group'

複製程式碼

引入之後,就可以使用這個元件了,方法是在外層增加標籤。

<ul ref={(ul)=>{this.ul=ul}}>
    <TransitionGroup>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </TransitionGroup>
</ul> 

複製程式碼

但是隻有這個是不夠的,你還是需要加入,來定義動畫。

<ul ref={(ul)=>{this.ul=ul}}>
    <TransitionGroup>
        <CSSTransition
            timeout={1000}
            classNames='boss-text'
            unmountOnExit
            appear={true}
            key={index+item}
        >
            <li>1</li>
        </CSSTransition>
        <CSSTransition
            timeout={1000}
            classNames='boss-text'
            unmountOnExit
            appear={true}
            key={index+item}
        >
            <li>2</li>
        </CSSTransition>
    </TransitionGroup>
</ul> 
複製程式碼

React動畫還有很多知識,能做出很多酷炫的效果,完全可以單獨分出來一個崗位,我在工作中用的都是比較簡單的動畫,用react-transition-group動畫已經完全可以滿足我的日常開發需求了


以上大部分內容和講解都來來自技術胖的部落格,結合了自己對react的理解。

相關文章