你真的了解setState 嗎?

2022-03-12 10:17:31 字數 2500 閱讀 5068

對於 setstate() 相信夥伴們都用過,它是 react 官方推薦用來更新元件 state 的 api,但是對於 setstate() 你真的了解嗎?且待我慢慢詳聊一番。

語法1:setstate(updater[, callback])

語法2:setstate(statechange[, callback])

對於這兩種形式,不同的是第乙個引數選擇問題,可以選擇乙個函式返回乙個新的state物件,亦可以直接選擇乙個物件應用於狀態更新,那麼啥時候選擇函式型別的引數,什麼時候選擇物件型別的呢?這裡可以總結兩句話:

這個例子中,我們通過點選按鈕測試1或測試2來改變元件 a 的 count 狀態值,因為每次修改狀態都是在原先基礎上加 1, 所以在setstate 中適合選擇函式型別引數,即 update2 寫法推薦。

我們知道setstate() 會觸發元件render() 函式,重新渲染元件將更新後的內容顯示在檢視上,那麼在 setstate() 之後我們立馬就能獲取到最新的state值嗎?

這裡涉及到乙個 setstate() 是非同步更新還是同步更新的問題?

結論:我們還是可以拿之前的按鈕點選例項來測試。

example:

我們在 react 事件監聽** update1 和 元件生命週期 componentwillmount() 鉤子裡面分別在setstate()之後列印最新的 state 值,發現列印出來的還是修改之前的state,但是頁面已經更新為最新狀態,看圖:

採用同樣的方法我們可以觀察在 update2 的settimeout() 和 update3 的 promise() **中,setstate() 後列印的是最新的state值,而且這個列印會在setstate() 觸發元件重新render() 之後。經過測試,恰好驗證了我們的結論是正確的,在react 相關的**中setstate()是非同步更新狀態,在不相關的**中 setstate() 是同步更新狀態。

這個問題其實是針對當setstate() 非同步更新狀態之後,怎麼立馬獲取到最新的狀態值,也就是上面例子我們說的在update1() 和componentwillmount()中怎麼列印出最新的state值。

答案其實非常簡單,也就是我們說到的setstate()傳參的第二個callback() 引數。setstate() 的第二個**會在更新狀態之後,元件重新render() 之後呼叫,也就是這裡面我們可以獲取到最新的狀態值。

**:

...

update1 = () => , () => )

}componentwillmount () ), () => )

}

這樣,我們同樣可以在update1 和 componentwillmount() 中 列印出最新的state值。

這裡我們討論的前提當然是setstate() 非同步更新狀態時候,因為同步更新,我們呼叫幾次 setstate(),就會觸發幾次 render鉤子,當然也會實時分別列印出更新後的狀態值。

結論:這裡分兩種情況討論:

可以看到,我們多次重複呼叫setstate(),不管是傳參是何種型別。react都只會呼叫一次 render,重新渲染元件。

我們可以同樣以按鈕點選例項來測試我們結論。

example:

當點選測試按鈕2,因為setstate() 是同步更新狀態,可以發現元件進行了多次render呼叫,分別依次列印出更新後的狀態值,這個很簡單。

我們點選測試按鈕1,分別對傳給setstate()引數不同進行了測試,發現當傳參是物件型別時候,react會合併重複setstate()呼叫,也就是只更新一次state狀態,傳函式型別引數時候,則分別進行了計算更新。

無論以哪種方式傳參重複呼叫 setstate() ,react 都只會進行一次render 呼叫,這也是效能優化的一部分,防止多次重複渲染帶來的效能問題。

其實官網推薦我們使用setstate()時候,第乙個引數傳函式型別引數,因為函式引數中接收的 state 和 props 都保證為最新。

你真的了解Java嗎?

三目運算子規則 如果第二個和第三個運算元具有相同的型別,那麼它就是條件表示式的類 型。換句話說,你可以通過繞過混合型別的計算來避免 煩。如果乙個運算元的型別是 t,t 表示 byte short 或 char,而另乙個運算元是乙個 int 型別的常量表示式,它的值是可以用型別 t 表示的,那麼條件表...

你真的了解restful api嗎?

在以前,乙個 的完成總是 all in one 頁面,資料,渲染全部在服務端完成,這樣做的最大的弊端是後期維護,擴充套件極其痛苦,開發人員必須同時具備前後端知識。於是慢慢的後來興起了前後端分離的思想 後端負責資料編造,而前端則負責資料渲染,前端靜態頁面呼叫指定api獲取到有固定格式的資料,再將資料展...

你真的了解git嗎?

看了幾遍廖雪峰的git教程和阮一峰的git教程之後,覺得自己使用git已經是得心應手了,腦中也構建出了一副關於git操作的影象。學習乙個新東西的時候我總是喜歡把知識形象化出乙個圖譜在腦中,這樣記憶的更加深刻。但是隨著使用的深入,我發現我腦中的影象與git的實際行為存在出入。稍微進入一下正題。假如你的...