此文主要探討了 React JS 中的 setState 背后的機制,供深入學習 React 研究之用。
在課程 React.js入門基礎與案例開發 中,有些同學會發現 React JS 中的 setState 的表現好像有點怪異,和理解中的 state 更新機制不太一樣,下面我們就來簡單探討下 setState 背后的機制。
課程中的其他常見小問題請常見 React.js 開發參見問題 Q&A。
1 setState 問題的復現
我們看下面一段簡單的代碼,代碼通過點擊一個按鈕,改變 state 中的 clicked 值。在修改值后進行 clicked 值的輸出,你嘗試猜測一下輸出的值是什么?
許多同學在自己寫代碼遇到類似邏輯的時候都會發現,console.log(this.state.clicked);
這段代碼輸出的不是我們預期的 true,而是 false。
這是為什么呢?
2 setState 的內部機制
遇到問題我們還是去官方文檔找線索。
我們看到 state 的章節有下面這段話。
文章鏈接在這里:https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous。
我們會發現其實 React 的 setState 方法是一個異步的方法,React 會將所有的 setState 方法打包成一次進行更新,類似於快遞點寄快遞,囤積了一些包裹后一次投遞,而不是你每次修改 state 都會進行更新。
這樣的設計主要是為了提高 UI 更新的性能,我們知道 React 中 state 的改變會導致 UI 的更新。
如果需要進行同步操作邏輯,那么在回調函數里添加邏輯即可。
{% codeblock lang:js%}
handleClick = () => {
this.setState({
clicked: true
}, () => console.log(this.state.clicked)) //這時候輸出的是 true
}
{% endcodeblock %}
3 state 的更新時機
任何 state 的更新都會導致 React 進行重新渲染。props
也會導致 React 進行重新渲染。組件與父組件的更改同樣也會引起 React 的重新渲染。
那么我們有沒有辦法手動控制 React 是否進行渲染呢?
這里,你應該想起來生命周期函數里有一個方法 shouldComponentUpdate
。
shouldComponentUpdate 方法官方文檔。
此方法默認每次在需要進行重新渲染時返回 true,但是在這個函數里你可以添加自己的邏輯,控制 React 不進行渲染以及渲染的條件。
那么,同樣,我們也可以在此函數中定義那些我們關注的 state ,只有當它們變化才讓 React 進行重新渲染,而其他一些不相關的 state 的值即使變化了,我們也可以讓 React 不進行渲染。
理解了這些,那么在你進行相關性能優化時就非常有用。