this.setState
如果需要修改this.state中的數據 必須調用this.setstate這個方法
這個方法里面有2個參數
參數1:類型 對象 key是this.state中的key值 val是修改后的數據
參數2:類型 函數 1、查看數據是否已經更新 2、可以獲取到數據更新后的最新的DOM結構
書寫方案1:this.setstate({},()=>{})
書寫方案2:this.setstate(()=({}),()=>{})
關於 setState() 有三件事是你應該知道的。
1.不要直接修改 state(狀態)
this.
state.comment = 'Hello';
上述代碼並不會重新渲染組件,需要使用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 就會以異步的方式執行。