React 之 setState

用途

React裏面的setState應該是最常用的api了。在React中,視圖組件都是基於數據的變化而更新的。那麼改變數據就離不開setState。下面看下基本的用法

//...
constructor(){
    super();
    this.state = {
        index: 0
    };
}

handleClick(){
    this.setState({
        index: 1
    });
}

render(){
    return (
        <div>{this.state.index}</div>
    )
}

我們通過setState改變了state中index的值,那麼引用該值的視圖就會被更新。

異步更新

稍微修改一下上面的代碼

this.setState({
    index: 1
});

console.log(this.state.index); //0

我們在調用setState後立刻對index值進行了輸出,此時我們會看到打印出來的值是0,並非我們設置的1。Why?

在官方的描述中,setState操作並不保證是同步的,也可以認爲是異步的。

React在setState之後,會經對state進行diff,判斷是否有改變,然後去diff dom決定是否要更新UI。如果這一系列過程立刻發生在每一個setState之後,就可能會有性能問題。比如:你在短時間內頻繁setState。React會將state的改變壓入棧中,在合適的時機,批量更新state和視圖,達到提高性能的效果。

那麼如何知道state已經被更新了呢?

方法一:

//api setState(updater, [callback])

setState({
    index: 1
}}, function(){
    console.log(this.state.index);
})

方法二:

componentDidUpdate(){
    console.log(this.state.index);
}

setState還可以接收function作爲參數

我們看下這樣一個場景

class Com extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            index: 0
        }
        this.add = this.add.bind(this);
    }

    add(){
        this.setState({
            index: this.state.index + 1
        });
        this.setState({
            index: this.state.index + 1
        });
    }
}

這裏我們執行add方法後,得到的結果是state中的index值爲1,並不是2。

原本的設想是每一次setState中,拿到的state都應該是已經改變過的值,但其實並不是。

這裏需要在每一次setState中,拿到上一次改變state後的值,在這個值的基礎上,再進行操作。顯然,對於setState這種異步的操作使用上面的寫法是達不到要求的,所以這裏React提供另一種方式。

//api (prevState, props) => stateChange

class Com extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            index: 0
        }
        this.add = this.add.bind(this);
    }

    add(){
        this.setState(prevState => {
            return {index: prevState.index + 1};
        });
        this.setState(prevState => {
            return {index: prevState.index + 1};
        });
    }
}

在setState的第一個參數中傳入function,該function會被壓入調用棧中,在state真正改變後,按順序回調棧裏面的function。該function的第一個參數爲上一次更新後的state。這樣就能確保你下一次的操作拿到的是你預期的值。

文章作者:forevercjl
原文鏈接:www.foreverpx.cn
轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章