當前位置:
首頁 > 最新 > React 是否保持 state 更新的順序?

React 是否保持 state 更新的順序?

stackoverflow 有人提問:Does React keep the order for state updates?

我知道 React 的狀態更新是非同步執行的,為了性格優化,狀態是批量更新的。所以你永遠不能確信在調用 後狀態是否更新了。但是你是否可以確認調用後狀態的更新順序呢?

比如以下情況:

相同的組件?

不同的組件?

考慮以下按鈕點擊的例子:

是否有可能是 , 是?

是否有可能是 , 是?

請記住,這是我對用例的極端簡化。我知道我可以改善我的代碼,例如,在例 1 中同時更新兩個 state 值,以及在例 2 中的第一個 的回調中執行第二個 。但是,這不是我的問題,而且我只想知道 React 執行這些狀態更新時有沒有確切的方式和順序,僅此而已。

不久後,React 的作者 Dan Abramov 親自來回答了。

I work on React.

開場定乾坤。很有力度的一句話。

TLDR:

很多英文文章中都會出現 TLDR,有時候會寫成 tl_dr、tl;dr,是 Too Long; Didn"t Read 的縮寫,作用就是告訴讀者,這篇內容篇幅比較長,如果不想深入探討或時間有限,可以看總結。

Dan Abramov 先給出了結論:

同一個組件中, 是否有確定的順序?是的

不同組件中, 是否有確定的順序?是的

狀態始終是按照特定的順序更新的。無論你是否看到介於兩個狀態之間的一個中間狀態,無論你是否在批處理內。

目前(React 16 及更早版本),默認情況下,只有 React 事件處理程序中的更新才會被批處理。有一個不穩定(unstable)的 API 來強制在事件處理程序之外進行批處理,以便在需要時處理罕見的情況。

在未來的版本(可能是 React 17 或更高版本)中,React 將默認批量更新所有更新,因此你不必考慮這一點。與往常一樣,我們將在 React 博客和 release note 中宣布對此的任何更改。

理解這一點的關鍵在於,在 React 事件處理程序中,不論 調用了多少次,也不論 被多少個組件調用,它們在事件結束時只會生成一次重新渲染。這對於大型應用程序性能至關重要,因為如果 與 處理 click 事件的時候都調用 ,你不希望重新渲染 兩次。

在這兩個例子中, 調用都發生在 事件處理程序中。因此,在事件結束時,他們總是被合併到一起(而且你看不到中間狀態)。

更新總是按照它們發生的順序進行淺合併(shallowly merge)。所以如果第一次更新是 ,第二次是 ,第三次 ,呈現的狀態將是 。對 中同一個 key 的更新(例如我的例子中 的更新),最新(近)的更新總是「勝出」。**

當我們在批處理結束時重新呈現 UI 時, 對象已經被更新了。所以如果你需要根據之前的狀態更新狀態(比如增加一個計數器),你應該使用 的回掉函數版本來提供之前的狀態,而不是讀取狀態 。如果你對這個理由感到好奇,我在這個評論中深入地解釋了它。

在你的例子中,我們不會看到「中間狀態」,因為我們在具有批處理功能的React 事件處理程序中(因為 React 「知道」什麼時候退出該事件)。

但是,在 React 16 和更早版本中,React 事件處理程序之外還沒有默認的批處理。因此,如果在你的例子中,我們吧 替換為 AJAX 處理程序,那麼每個 都會立即處理。在這種情況下,是的,你看到一個中間狀態:

我們認識到,根據是否處於事件處理程序中,行為是不同的,這是不方便的。這將在未來的 React 版本中進行更改,默認情況下將批量更新所有更新(並提供選擇性 API 以同步刷新更改)。直到我們切換默認行為(可能在 React 17 中),有一個 API 可以用來強制批量處理:

在 React 內部,事件處理程序都被包裝在 內,這就是默認情況下批處理的原因。請注意,將 封裝 兩次是不起作用的。當我們退出最外層的 調用時,更新被刷新。

該 API 是「不穩定的」,因為如果默認情況下已經啟用批處理,我們將刪除它。但是,在 React 小版本中我們不會刪除它,所以在 React 17 之前,如果你需要在 React 事件處理程序之外的某些情況下強制批處理,你可以安全地依賴它。

總之,這是一個令人困惑的話題,因為 React 默認只在事件處理程序中進行批處理。這將在未來的版本中發生變化,那麼行為將更直接。但解決方案不是減少批處理,而是默認開啟更多的批處理。這就是我們要做的。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 justjavac 的精彩文章:

TAG:justjavac |