this.setState
若是須要修改this.state中的數據 必須調用this.setstate這個方法
這個方法裏面有2個參數
參數1:類型 對象 key是this.state中的key值 val是修改後的數據
參數2:類型 函數 一、查看數據是否已經更新 二、能夠獲取到數據更新後的最新的DOM結構
書寫方案1:this.setstate({},()=>{})
書寫方案2:this.setstate(()=({}),()=>{})
關於 setState() 有三件事是你應該知道的。
1.不要直接修改 state(狀態)
上述代碼並不會從新渲染組件,須要使用this.setState()代替:
this.setState({
comment: 'Hello'
});
須要注意的是惟一能夠分配 this.state 的地方是構造函數。
2.state(狀態) 更新多是異步的
React 爲了優化性能,有可能會將多個 setState() 調用合併爲一次更新。
由於this.props和this.state 多是異步更新的,你不能依賴他們的值計算下一個state(狀態)。如下面的代碼爲例:
this.setState({
counter: this.state.counter + this.props.increment,
});
咱們並不能經過上述代碼獲得想要的值,爲了彌補這個問題,使用另外一種 setState() 的形式,接受一個函數。這個函數將接收前一個狀態做爲第一個參數,應用更新時的 props 做爲第二個參數,代碼以下:
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
3.state(狀態)更新會被合併
當你調用 setState(), React 將合併你提供的對象到當前的狀態中。因此當State是一個多鍵值的結構時,能夠單獨更新其中的一個,此時會進行「差分」更新,不會影響其餘的屬性值。
setState()的異步更新。
1.執行setState()以後幹了什麼?
setState()方法經過一個隊列機制實現state更新,當執行setState()的時候,會將須要更新的state合併以後放入狀態隊列,而不會當即更新this.state(能夠和瀏覽器的事件隊列類比)。若是咱們不使用setState而是使用this.state.key來修改,將不會觸發組件的re-render。若是將this.state賦值給一個新的對象引用,那麼其餘不在對象上的state將不會被放入狀態隊列中,當下次調用setState()並對狀態隊列進行合併時,直接形成了state丟失。
2.setState()能夠接受一個函數做爲參數?
setState() 不只可以接受一個對象做爲參數,還可以接受一個函數做爲參數。函數的參數即爲 state 的前一個狀態以及 props。
React文檔中對setState的說明以下:
void setState (
function|object nextState,
[function callback]
)
上述代碼的第二個參數是一個回調函數,在setState() 的異步操做結束而且組件已經從新渲染的時候執行。換句話說,咱們能夠經過這個回調來拿到更新的state的值。
3.執行setState()後能拿到最新的state值嗎?
之前在寫代碼時候,老是遇到明明執行過setState(),可是state的值卻不是最新的,那麼如何解決這個問題呢?
由於setState()函數接受兩個參數,一個是一個對象,就是設置的狀態,還有一個是一個回調函數,是在設置狀態成功以後執行的,因此咱們能夠經過回掉拿到最新的state值。代碼以下:
updateData = (newData) => {
this.setState(
{ data: newData },
() => {
//這裏打印的是最新的state值
console.log(that.state.data);
}
);
}
4.setState()必定是異步更新嗎?
咱們先來看看下面的代碼:
function incrementMultiple() {
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
}
直觀上來看,當上面的 incrementMultiple 函數被調用時,組件狀態的 count 值被增長了3次,每次增長1,那最後 count 被增長了3。可是,實際上的結果只給 state 增長了1。
事實上,setState 方法與包含在其中的執行是一個很複雜的過程,從 React 最初的版本到如今,也有無數次的修改。它的工做除了要更動 this.state 以外,還要負責觸發從新渲染,這裏面要通過 React 核心 diff 算法,最終才能決定是否要進行重渲染,以及如何渲染。並且爲了批次與效能的理由,多個 setState 呼叫有可能在執行過程當中還須要被合併,因此它被設計以延時的來進行執行是至關合理的。
在 React 的 setState 函數實現中,會根據一個變量 isBatchingUpdates 判斷是直接更新 this.state 仍是放到隊列中回頭再說,而 isBatchingUpdates 默認是 false,也就表示 setState 會同步更新 this.state,可是,有一個函數 batchedUpdates,這個函數會把 isBatchingUpdates 修改成 true,而當 React 在調用事件處理函數以前就會調用這個 batchedUpdates,形成的後果,就是由 React 控制的事件處理過程 setState 不會同步更新 this.state。
由 React 控制的事件處理過程 setState 不會同步更新 this.state!
也就是說,在 React 控制以外的狀況, setState 會同步更新 this.state!
但大部份的使用狀況下,咱們都是使用了 React 庫中的表單組件,例如 select、input、button 等等,它們都是 React 庫中人造的組件與事件,是處於 React 庫的控制之下,好比組件原色 onClick 都是通過 React 包裝。在這個狀況下,setState 就會以異步的方式執行。