更合理的使用setState

2022-09-21 20:00:24 字數 3335 閱讀 1127

react中的setstate()為我們提供了元件內的狀態管理方案,

本文將從component的角度來說明更合理的setstate()

在 react 文件的 

state and lifecycle

一章中,明確的說明setstate()的用法,向setstate()中傳入乙個物件來對已有的 state 進行更新。

我們如果想要對這個 state 進行更新的話,就可以這樣使用setstate()

this.setstate();
你可能不知道的

最基本的用法世人皆知,但是,在 react 的文件下面,還寫著,處理關於非同步更新 state 的問題的時候,就不能簡單地傳入物件來進行更新了。這個時候,需要採用另外一種方式來對 state 進行更新。

setstate()不僅能夠接受乙個物件作為引數,還能夠接受乙個函式作為引數。函式的引數即為 state 的前乙個狀態以及 props。

所以,我們可以向下面這樣來更新 state:

this.setstate((prevstate, props) => ());
這樣寫的話,能夠達到同樣的效果。那麼,他們之間有什麼區別呢?

區別為了能夠明確的看出 state 的更新,

採用乙個比較簡單的例子來進行說明。

設定乙個累加器,在 state 上設定乙個count屬性,同時,為其增加乙個increment方法,通過這個increment方法來更新count

此處,採用給setstate()傳入物件的方式來更新 state,同時,在此處設定每呼叫一次increment方法的時候,就呼叫兩次setstate()。具體的原因我在後文中會講解。

具體的**如下:

class

incrementbyobject

extends

react.component ;

this.increment = this.increment.bind(this);

} // 此處設定呼叫兩次 setstate()

increment() );

this.setstate();

} render() >incrementbyobjectbutton>

span>

div>

);}}

reactdom.render(

, document.getelementbyid('root')

);

這時候,點選 button 的時候,count就會更新了。但是,可能與預期的有所差別。設定了點選一次就呼叫兩次setstate(),但是,count每一次卻還是只增加了 1,所以這是為什麼呢?

其實,在 react 內部,對於這種情況,採用的是物件合併的操作,就和我們所熟知的object.assign()執行的結果一樣。

比如,我們有以下的**:

object.assign({}, , );
那麼,最終得到的結果將會是。物件合併的操作,屬性值將會以最後設定的屬性的值為準,如果發現之前存在相同的屬性,那麼,這個屬性將會被後設定的屬性所替換。所以,也就不難理解為什麼呼叫了兩次setstate()之後,count依然只增加了 1 了。

用簡短的**說明就是這樣:

this.setstate();

// 同理於

object.assign({}, this.state, );

以上是採用物件的方式傳入setstate()來更新 state 的說明。接下來再看看使用函式的方式來更新 state 會有怎麼樣的效果呢?

將上面的累加器採用另外的方式來實現一次,在setstate()的時候,用傳入乙個函式的方式來更新 state。

class

incrementbyfunction

extends

react.component ;

this.increment = this.increment.bind(this);

} increment() ));

this.setstate((prevstate, props) => ());

} render() >incrementbyfunctionbutton>

span>

div>

);}}

reactdom.render(

, document.getelementbyid('root')

);

當再次點選按鈕的時候,就會發現,累加器就會每次增加 2 了。

可以通過檢視 react 的源**來找出這兩種更新 state 的區別 (此處只展示通過傳入函式進行更新的方式的部分原始碼)。

在 react 的源**中,可以看到這樣一句**:

this.updater.enqueuesetstate(this, partialstate, callback, 'setstate');
然後,enqueuesetstate函式中又會有這樣的實現:

queue.push(partialstate);

enqueueupdate(internalinstance);

所以,與傳入物件更新 state 的方式不同,傳入函式來更新 state 的時候,react 會把更新 state 的函式加入到乙個佇列裡面,然後,按照函式的順序依次呼叫。同時,為每個函式傳入 state 的前乙個狀態,這樣,就能更合理的來更新 state 了。

問題所在

那麼,這就是傳入物件來更新 state 會導致的問題嗎?當然,這只是問題之一,還不是主要的問題。

之前也說過,在處理非同步更新的時候,需要用到傳入函式的方式來更新state。這樣,在更新下乙個 state 的時候,我們能夠正確的獲取到之前的 state,並在在其基礎之上進行相應的修改。而不是簡單地執行所謂的物件合併。

所以說,我們建議,在使用setstate的時候,採用傳入函式來更新 state 的方式,這樣也是乙個更合理的方式。

setstate

PCB如何更合理的拼版

1 pcb拼板的外框 夾持邊 應採用閉環設計,確保pcb拼板固定在夾具上以後不會變形 2 pcb拼板寬度 260mm siemens線 或 300mm fuji線 如果需要自動點膠,pcb拼板寬度 長度 125 mm 180 mm 3 pcb拼板外形盡量接近正方形,推薦採用2 2 3 3 拼板 但不...

怎樣的工作量評估更合理?

如果你在外包公司工作過,或者你正在外包公司工作。我相信你一定會遇到評估專案工作量的情況,或者你是評估其中一部分的功能。在pmp裡面介紹,評估工作量最好是找最熟悉這個功能的人,也就是專家判斷。所以肯定非你莫屬了,畢竟你已經成為了專家。但我相信也肯定會遇到一種情況,工作量評估提交給客戶後,客戶開始砍工作...

linux c結構體更合理的初始化方法

教科書上講c語言結構體初始化是按照順序方式來講的,沒有涉及到亂序的方式。順序初始化struct必須要按照成員的順序進行,缺一不可,如果結構體比較大,很容易出現錯誤,而且表現形式不直觀,不能一眼看出各個struct各個資料成員的值。亂序初始化是c99標準新加的,比較直觀的一種初始化方式。相比順序初始化...