淺談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
的值進行加1
,render()
應該會執行兩次,最後count
的值應該是2。但是 React 並不是這麼執行的。
以上代碼放到瀏覽器運行一下即可:
最開始時,頁面顯示count
的值為0
,控制臺打印出render
,這是 React 首次渲染時打印的。當點擊完按鈕後,頁面顯示count
值是1
,同時也隻打印瞭1
個render
,說明在這過程中 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 中直接使用的事件,如onChange
、onClick
等,都是由 React 封裝後的事件,是合成事件,由 React 管理。
React 對於合成事件和生命周期函數,有一套性能優化機制,會合並多個setState
,若出現同名屬性,會將後面的同名屬性覆蓋掉前面的同名屬性。
若越過 React 的性能優化機制,在原生事件、setTimeout
中使用setState
,就不歸 React 管理瞭,寫瞭幾次setState
,就會調用幾次setState
。
到此這篇關於淺談React多個setState會調用幾次的文章就介紹到這瞭,更多相關淺談React多個setState會調用幾次內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 關於React中setState同步或異步問題的理解
- React 原理詳解
- react使用useState修改對象或者數組的值無法改變視圖的問題
- React setState是異步還是同步原理解析
- 代碼解析React中setState同步和異步問題