在 React 中,如果是由 React 引發(fā)的事件處理(比如通過 onClick 引發(fā)的事件處理),調用 setState 不會同步更新 this.state,除此之外的 setState 調用會同步執(zhí)行 this.state。所謂“除此之外”,指的是繞過 React 通過 addEventListener 直接添加的事件處理函數,還有通過 setTimeout/setInterval 產生的異步調用。
**原因:**在 React 的 setState 函數實現中,會根據一個變量isBatchingUpdates判斷是直接更新 this.state 還是放到隊列中回頭再說,而 isBatchingUpdates 默認是 false,也就表示 setState 會同步更新 this.state,但是,有一個函數 batchedUpdates,這個函數會把 isBatchingUpdates 修改為t rue,而當 React 在調用事件處理函數之前就會調用這個 batchedUpdates,造成的后果就是由 React 控制的事件處理過程 setState 不會同步更新 this.state。
在React的setState函數實現中,會根據一個變量 isBatchingUpdate 來判斷是直接同步更新this.state還是放到隊列中異步更新 。React使用了事務的機制,React的每個生命周期和合成事件都處在一個大的事務當中。在事務的前置鉤子中調用batchedUpdates方法修改isBatchingUpdates變量為true,在后置鉤子中將變量置為false。原生綁定事件和setTimeout異步的函數沒有進入到React的事務當中,或者當他們執(zhí)行時,剛剛的事務已近結束了,后置鉤子觸發(fā)了,所以此時的setState會直接進入非批量更新模式,表現在我們看來成為了同步SetState
https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/18
詳見