淺談React多個setState會調用幾次

1. 兩個setState,調用幾次?

如下代碼所示,state中有一個count。對按鈕綁定瞭點擊事件,事件中執行瞭兩次setState,每次都將count的值加1

當點擊按鈕時,setState會執行幾次?render()會執行幾次?

答案:都是1次。

state = { count: 0 };
handleClick = () => {
    this.setState({ count: this.state.count + 1 });
    this.setState({ count: this.state.count + 1 });
};
render() {
    console.log(`render`);
    return (
        <>
            <div>當前計數:{this.state.count}</div>
            <button onClick={this.handleClick}>add</button>
        </>
    );
}

按照常理來說,第一次點擊按鈕時,由於執行瞭兩次兩次setState,每次都將count的值進行加1render()應該會執行兩次,最後count的值應該是2。但是 React 並不是這麼執行的。

以上代碼放到瀏覽器運行一下即可:

最開始時,頁面顯示count的值為0,控制臺打印出render,這是 React 首次渲染時打印的。當點擊完按鈕後,頁面顯示count值是1,同時也隻打印瞭1render,說明在這過程中 React 隻執行瞭一次setState,隻執行瞭一次render()渲染操作。

原因在於,React 內部將同一事件響應函數中的多個setState進行合並,減少setState的調用次數,也就能減少渲染的次數,提高性能。

這也就解釋瞭上述代碼,為什麼最後count的值是1,因為 React 將兩個setState進行瞭合並,最終隻執行瞭1次,render()也隻執行瞭一次。

2. 兩個setState,調用的是哪一個?

但上述代碼沒有驗證,React 合並後,到底執行的是哪一次setState。如下代碼所示,將第二個setState中,對count的操作改為加2,其餘代碼保持不變:

state = { count: 0 };
handleClick = () => {
    this.setState({ count: this.state.count + 1 });
    this.setState({ count: this.state.count + 2 }); // 改為+2
};
render() {
    console.log(`render`);
    return (
        <>
            <div>當前計數:{this.state.count}</div>
            <button onClick={this.handleClick}>add</button>
        </>
    );
}

再次放到瀏覽器中執行:

結果顯示,點擊按鈕後,count的值最終變成瞭2,也就是進行瞭+2的操作,render()也隻執行瞭1次。這就說明 React 在合並多個setState時,若出現同名屬性,會將後面的同名屬性覆蓋掉前面的同名屬性。可以這麼理解,對於同名屬性,最終執行的的是最後setState中的屬性。

3. 兩個setState放在setTimeout中?

若在點擊事件函數中,添加一個定時器setTimeout,在定時器中執行兩次setState操作,結果又將如何?如下代碼,事件處理函數中,寫瞭一個定時器setTimeout,將兩次setState放入setTimeout中。

state = { count: 0 };
handleClick = () => {
    setTimeout(() => {
        this.setState({ count: this.state.count + 1 });
        this.setState({ count: this.state.count + 2 });
    }, 0);
};
render() {
    console.log(`render`);
    return (
        <>
            <div>當前計數:{this.state.count}</div>
            <button onClick={this.handleClick}>add</button>
        </>
    );
}

運行結果:

結果顯示,點擊按鈕後,count的值最終變成瞭3,也就+1+2的操作都執行瞭,render()也執行瞭2次。

這是因為在 React 的合成事件生命周期函數中直接調用setState,會交由 React 的性能優化機制管理,合並多個setState。而在原生事件setTimeout中調用setState,是不受 React 管理的,故並不會合並多個setState,寫瞭幾次setState,就會調用幾次setState

4. 總結

在 React 中直接使用的事件,如onChangeonClick等,都是由 React 封裝後的事件,是合成事件,由 React 管理。

React 對於合成事件和生命周期函數,有一套性能優化機制,會合並多個setState,若出現同名屬性,會將後面的同名屬性覆蓋掉前面的同名屬性

若越過 React 的性能優化機制,在原生事件setTimeout中使用setState,就不歸 React 管理瞭,寫瞭幾次setState,就會調用幾次setState

到此這篇關於淺談React多個setState會調用幾次的文章就介紹到這瞭,更多相關淺談React多個setState會調用幾次內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: