React 是否保持 state 更新的順序

React狀態更新是異步的,爲了性能優化,狀態更新都是批量更新的。
但是否可以確認 setState 調用後狀態的更新順序呢?

Dan Abramov 先給出了結論:

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

狀態始終是按照特定的順序更新的。無論你是否看到介於兩個狀態之間的一箇中間狀態,無論你是否在批處理內。
目前(React 16 及更早版本),默認情況下,只有 React 事件處理程序中的更新纔會被批處理。有一個不穩定(unstable)的 API 來強制在事件處理程序之外進行批處理,以便在需要時處理罕見的情況。
在未來的版本(可能是 React 17 或更高版本)中,React 將 默認批量更新所有更新
在 React 事件處理程序中,不論 setState() 調用了多少次,也不論 setState()被多少個組件調用,它們在事件結束時只會生成一次重新渲染
在這兩個例子中,setState() 調用都發生在 React 事件處理程序中。因此,在事件結束時,他們總是被合併到一起(而且你看不到中間狀態)
更新總是 按照它們發生的順序進行淺合併(shallowly merge)
在 React 16 和更早版本中,React 事件處理程序之外還沒有默認的批處理。因此,如果在例子中,我們把 handleClick 替換爲 AJAX 處理程序,那麼每個 setState() 都會立即處理。在這種情況下,你會看到一箇中間狀態:

promise.then(() => {
  // 我們不在事件處理程序中,因此它們都會被刷新。
  this.setState({a: true}); // 使用 {a: true, b: false } 重新渲染
  this.setState({b: true}); // 使用 {a: true, b: true } 重新渲染
  this.props.setParentState(); // 重新渲染父組件
});

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

promise.then(() => {
  // 強制批量處理
  ReactDOM.unstable_batchedUpdates(() => {
    this.setState({a: true}); // 不重新渲染
    this.setState({b: true}); // 不重新渲染
    this.props.setParentState(); // 不重新渲染
  });
  // 當我們退出 unstable_batchedUpdates函數後,重新渲染一次
});

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章