成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聊聊setState的用法,你會幾個?

開發 前端
首先,這個問題的拋出,我會想為什么要拋出這個問題呢?如果說,你需要依賴狀態更新后的值時,那么首先如何做呢?

[[387190]]

本文轉載自微信公眾號「前端UpUp」,作者前端UpUp。轉載本文請聯系前端UpUp公眾號。

setState是同步還是異步?

首先,這個問題的拋出,我會想為什么要拋出這個問題呢?如果說,你需要依賴狀態更新后的值時,那么首先如何做呢?

  • 對于Class Component而言,我們可以在componentDidMount或者是componentDidUpdate階段來執行。
  • 對于Function Component而言,我們可以在useEffect的回調函數中執行。

首先,我們先給出結論,在React中不同的模式它的情況是不一樣的,主要拿兩種模式來說。

  1. legacy模式
  2. concurrent模式

legacy 模式

這是當前 React app 使用的方式??

  1. ReactDOM.render(<App />, rootNode) 

當前沒有計劃刪除本模式,但是這個模式可能不支持這些新功能。

回到我們上述的問題,setState是同步的還是異步的?

  • 當在legacy模式下,命中batchedUpdates時,setState是異步的。
  • 當在legacy模式下,沒命中batchedUpdates時,setState是同步的。

既然聊到了這里,我們來說一說batchedUpdates函數的作用。

那么它是干嘛的呢?如果你在處理邏輯函數中多次調用this.setState時,它是如何更新狀態的呢?

  1. this.setState({ 
  2.   value: this.state.value + 1 
  3. }) 
  4. this.setState({ 
  5.   value: this.state.value + 1 
  6. }) 
  7. this.setState({ 
  8.   value: this.state.value + 1 
  9. }) 

那React實現了這個批量更新的操作,將多次的setState合并為一次更新,那么它是如何實現的呢?batchedUpdates函數就登場了。

  1. function batchedUpdates$1(fn, a) { 
  2.     var prevExecutionContext = executionContext; 
  3.     executionContext |= BatchedContext; 
  4.  
  5.     try { 
  6.       return fn(a); 
  7.     } finally { 
  8.       executionContext = prevExecutionContext; 
  9.  
  10.       if (executionContext === NoContext) { 
  11.         // Flush the immediate callbacks that were scheduled during this batch 
  12.         resetRenderTimer(); 
  13.         flushSyncCallbackQueue(); // 同步的更新 
  14.       } 
  15.     } 
  16.   } 

這個函數會傳遞一個fn,當執行fn之前,會在executionContext變量上附加一個BatchedContext,當fn執行完畢后,executionContext就會把之前的BatchedContext標記給去除掉。

  • 這樣子一來,當executionContext帶上了BatchedContext標記的話,react內部就會去做判斷,帶上了這個標記,這次的更新就是批處理,那么此次更新就是異步的。

那么,我們是不是能夠假設一下,如果在執行完fn函數后,再去更新狀態的話,是不是就能完成同步的更新呢?

setTimeout函數,我們可以把setState放在定時器中,這樣子一來的話,當fn函數執行完時,BatchedContext標記也去掉了,然后等到 setTimeout 的回調函數等到空閑被執行的時候,才會執行 setState。

  1. setTimeout(() => { 
  2.     this.setState({ value: this.state.value + 1}) 
  3.   }, 0) 

這也就是當executionContext === NoContext,也就是會執行flushSyncCallbackQueue函數,完成此次的同步更新。

當然了,在concurrent 模式下,又是有所不同的。

這個時候,我們得談一談scheduleUpdateOnFiber函數。

我們都知道任務調度的起點是 scheduleUpdateOnFiber 方法,React.render、setState、forceUpdate、React Hooks 的dispatchAction 都會經過 scheduleUpdateOnFiber。

  1. function scheduleUpdateOnFiber(fiber, lane, eventTime) { 
  2.     // ... 
  3.     if (root === workInProgressRoot) { 
  4.       // ......  
  5.     } // TO an argument to that function and this one. 
  6.     if (lane === SyncLane) {  // 同步任務 
  7.       if ( // 檢查當前是不是在unbatchedUpdates(非批量更新),(初次渲染的ReactDOM.render就是unbatchedUpdates) 
  8.       (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering 
  9.       (executionContext & (RenderContext | CommitContext)) === NoContext) { 
  10.         // Register pending interactions on the root to avoid losing traced interaction data. 
  11.         schedulePendingInteractions(root, lane);  
  12.         performSyncWorkOnRoot(root); 
  13.       } else { 
  14.         ensureRootIsScheduled(root, eventTime); 
  15.         schedulePendingInteractions(root, lane); 
  16.         if (executionContext === NoContext) { 
  17.           resetRenderTimer(); 
  18.           flushSyncCallbackQueue(); 
  19.         } 
  20.       } 
  21.     } else { // 異步任務 
  22.       // concurrent模式下是跳過了 flushSyncCallbackQueue 同步更新 
  23.       // .... 
  24.     }  
  25.   } 

scheduleUpdateOnFiber函數通過lane === SyncLane來判斷是同步任務還是異步任務,我們通過ReactDom.render()方式創建的React app是會進入這個判斷的,而concurrent模式下,則不同,那么它是如何創建的呢??

concurrent 模式

你可以理解成,這個暫時還是實驗階段,當未來穩定后,將會作為React開發的默認開發模式,它是如何創建一個React App應用的呢??

  1. ReactDOM.createRoot(rootNode).render(<App />) 

這個模式開啟了所有的新功能。

concurrent模式下狀態的更新都是異步的。

關于React的concurrent 模式解讀,有興趣可以看看官方文檔。

到這里的話,似乎我們對React中setState是同步的還是異步的就有所了解了。

 

  • 哪些會命中batchUpdate機制
  • 生命周期(和它調用函數)
  • React中注冊的事件
  • React可以'管理入口'

 

責任編輯:武曉燕 來源: 前端UpUp
相關推薦

2022-04-06 07:32:41

Java運算符變量

2022-06-04 08:29:27

awk命令BEGIN

2022-03-01 07:52:38

鏈表指針節點

2023-09-13 08:00:57

云原生Java開發者

2019-11-22 09:30:59

設計Java程序員

2020-04-07 08:51:25

CCNP協議網絡協議路由

2022-04-13 09:01:45

SASSCSS處理器

2022-03-03 07:34:31

注解容器作用域

2021-11-29 11:11:45

SQL查詢技巧

2021-09-12 17:25:12

SQLite數據庫

2024-04-26 08:10:49

2021-08-16 08:12:04

SQLMerge用法

2021-03-02 07:33:13

開發C#字符

2022-06-07 23:28:05

線程安全后端

2021-06-05 23:39:52

c++函數場景

2021-02-01 23:23:39

FiddlerCharlesWeb

2022-05-11 08:22:54

IO負載NFSOS

2025-03-25 10:49:13

2018-02-25 10:45:08

Linux命令uptime

2019-04-15 13:24:31

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 天天天操 | 91高清视频 | 久久久美女 | 日韩精品视频一区二区三区 | 日韩欧美不卡 | 日韩精品在线网站 | 天天插天天操 | 国产精品久久久久无码av | 九九九精品视频 | 久久国产精品视频观看 | 日韩蜜桃视频 | 伊人伊成久久人综合网站 | 亚洲在线免费观看 | 在线免费看91 | 久久久久久国产精品免费免费狐狸 | 亚洲一区成人 | 全免费a级毛片免费看视频免费下 | 国产精品视频网站 | 伊人网综合在线 | 啪啪毛片| 欧美一区二区三区在线观看 | 依人成人 | 女生羞羞网站 | 四虎国产| 毛片视频网址 | 情侣黄网站免费看 | 国产精品久久久亚洲 | 精品一区二区在线观看 | 成人在线一区二区 | 羞羞午夜| 成人精品一区二区三区中文字幕 | 香蕉一区| 中文在线视频观看 | 青娱乐av | 国产999精品久久久影片官网 | a久久| 欧美一区二区三区在线看 | 国产精品成人在线 | 成人片网址 | 欧美影院久久 | 91av视频在线观看 |