首頁 >web前端 >前端問答 >react的setstate什麼時候同步

react的setstate什麼時候同步

藏色散人
藏色散人原創
2023-01-06 10:46:552158瀏覽

react的setstate在原生事件和setTimeout中都是「同步」的,而在合成事件和鉤子函數中是「非同步」的;在React中,如果是由React引發的事件處理,調用setState不會同步更新“this.state”,除此之外的setState呼叫會同步執行“this.state”。

react的setstate什麼時候同步

本教學操作環境:Windows10系統、react18.0.0版、Dell G3電腦。

react的setstate什麼時候會同步?什麼時候是異步的? 

先給予答案: 

#有時表現出非同步,有時表現出同步。

setState只在合成事件和鉤子函數中是「非同步」的,在原生事件和setTimeout 中都是同步的。

class Example extends React.Component {
  constructor() {
    super();
    this.state = {
      val: 0
    };
  }
  
  componentDidMount() {
    this.setState({val: this.state.val + 1});
    console.log(this.state.val);    // 第 1 次 log
    this.setState({val: this.state.val + 1});
    console.log(this.state.val);    // 第 2 次 log
    setTimeout(() => {
      this.setState({val: this.state.val + 1});
      console.log(this.state.val);  // 第 3 次 log
      this.setState({val: this.state.val + 1});
      console.log(this.state.val);  // 第 4 次 log
    }, 0);
  }
  render() {
    return null;
  }
};

1.setState只在合成事件和鉤子函數中是「非同步」的,在原生事件和setTimeout 中都是同步的。

2.setState 的「非同步」並不是說內部由非同步程式碼實現,其實本身執行的過程和程式碼都是同步的,只是合成事件和鉤子函數的呼叫順序在更新之前,

導致在合成事件和鉤子函數中沒法立馬拿到更新後的值,形成了所謂的“異步”,當然可以透過第二個參數setState(partialState, callback) 中的callback拿到更新後的結果。

3.setState 的批次更新最佳化也是建立在「非同步」(合成事件、鉤子函數)之上的,在原生事件和setTimeout 中不會批次更新,

在「非同步「中如果對同一個值進行多次setState,setState的批次更新策略會對其進行覆蓋,取最後一次的執行,如果是同時setState多個不同的值,在更新時會對其進行合併批量更新。

在React中,如果是由React引發的事件處理(例如透過onClick引發的事件處理),呼叫setState不會同步更新this.state,除此之外的setState呼叫會同步執行this. state。所謂“除此之外”,指的是繞過React透過addEventListener直接加入的事件處理函數,還有透過setTimeout/setInterval產生的非同步呼叫。

原因:

在React的setState函數實作中,會根據一個變數isBatchingUpdates判斷是直接更新this.state還是放到佇列中回頭再說,而isBatchingUpdates預設是false,也就表示setState會同步更新this.state,但是,有一個函數batchedUpdates,這個函數會把isBatchingUpdates修改為true,而當React在呼叫事件處理函數之前就會呼叫這個batchedUpdates,造成的後果,就是React控制的事件處理過程setState不會同步更新this.state。

詳細請看 https://github.com/LuNaHaiJiao/blog/issues/26

推薦學習:《react影片教學

以上是react的setstate什麼時候同步的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn