精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

React 架構的演變 - Hooks 的實現

開發 架構
React Hooks 可以說完全顛覆了之前 Class Component 的寫法,進一步增強了狀態復用的能力,讓 Function Component 也具有了內部狀態,對于我個人來說,更加喜歡 Hooks 的寫法。

[[348911]]

React Hooks 可以說完全顛覆了之前 Class Component 的寫法,進一步增強了狀態復用的能力,讓 Function Component 也具有了內部狀態,對于我個人來說,更加喜歡 Hooks 的寫法。當然如果你是一個使用 Class Component 的老手,初期上手時會覺得很苦惱,畢竟之前沉淀的很多 HOC、Render Props 組件基本沒法用。而且之前的 Function Component 是無副作用的無狀態組件,現在又能通過 Hooks 引入狀態,看起來真的很讓人疑惑。Function Component 的另一個優勢就是可以完全告別 this ,在 Class Component 里面 this 真的是一個讓人討厭的東西?? 。

Hook 如何與組件關聯

在之前的文章中多次提到,Fiber 架構下的 updateQueue、effectList 都是鏈表的數據結構,然后掛載的 Fiber 節點上。而一個函數組件內所有的 Hooks 也是通過鏈表的形式存儲的,最后掛載到 fiber.memoizedState 上。

  1. function App() { 
  2.   const [num, updateNum] = useState(0) 
  3.  
  4.   return <div 
  5.     onClick={() => updateNum(num => num + 1)} 
  6.   >{ num }</div> 
  7.  
  8. export default App 

我們先簡單看下,調用 useState 時,構造鏈表的過程:

  1. var workInProgressHook = null 
  2. var HooksDispatcherOnMount = { 
  3.   useState: function (initialState) { 
  4.     return mountState(initialState) 
  5.   } 
  6.  
  7. function function mountState(initialState) { 
  8.   // 新的 Hook 節點 
  9.   var hook = mountWorkInProgressHook() 
  10.   // 緩存初始值 
  11.   hook.memoizedState = initialState 
  12.   // 構造更新隊列,類似于 fiber.updateQueue 
  13.   var queue = hook.queue = { 
  14.     pending: null
  15.     dispatch: null
  16.     lastRenderedState: initialState 
  17.   } 
  18.   // 用于派發更新 
  19.   var dispatch = queue.dispatch = dispatchAction.bind( 
  20.     null, workInProgress, queue 
  21.   ) 
  22.   // [num, updateNum] = useState(0) 
  23.   return [hook.memoizedState, dispatch] 
  24.  
  25. function mountWorkInProgressHook() { 
  26.   var hook = { 
  27.     memoizedState: null
  28.     baseState: null
  29.     baseQueue: null
  30.     queue: null
  31.     nextnull 
  32.   } 
  33.  
  34.   if (workInProgressHook === null) { 
  35.     // 構造鏈表頭節點 
  36.     workInProgress.memoizedState = workInProgressHook = hook 
  37.   } else { 
  38.     // 如果鏈表已經存在,在掛載到 next 
  39.     workInProgressHook = workInProgressHook.next = hook 
  40.   } 
  41.  
  42.   return workInProgressHook 

如果此時有兩個 Hook,第二個 Hook 就會掛載到第一個 Hook 的 next 屬性上。

  1. function App() { 
  2.   const [num, updateNum] = useState(0) 
  3.   const [str, updateStr] = useState('value: '
  4.  
  5.   return <div 
  6.     onClick={() => updateNum(num => num + 1)} 
  7.   >{ str } { num }</div> 
  8.  
  9. export default App 

Hook

Hook 的更新隊列

Hook 通過 .next 彼此相連,而每個 Hook 對象下,還有個 queue 字段,該字段和 Fiber 節點上的 updateQueue 一樣,是一個更新隊列在,上篇文章 《React 架構的演變-更新機制》中有講到,React Fiber 架構中,更新隊列通過鏈表結構進行存儲。

  1. class App extends React.Component { 
  2.   state = { val: 0 } 
  3.   click () { 
  4.     for (let i = 0; i < 3; i++) { 
  5.       this.setState({ val: this.state.val + 1 }) 
  6.     } 
  7.   } 
  8.   render() { 
  9.     return <div onClick={() => { 
  10.       this.click() 
  11.     }}>val: { this.state.val }</div> 
  12.   } 

點擊 div 之后,產生的 3 次 setState 通過鏈表的形式掛載到 fiber.updateQueue 上,待到 MessageChannel 收到通知后,真正執行更新操作時,取出更新隊列,將計算結果更新到 fiber.memoizedState。

setState

而 hook.queue 的邏輯和 fiber.updateQueue 的邏輯也是完全一致的。

  1. function App() { 
  2.   const [num, updateNum] = useState(0) 
  3.  
  4.   return <div 
  5.     onClick={() => { 
  6.       // 連續更新 3 次 
  7.       updateNum(num => num + 1) 
  8.       updateNum(num => num + 1) 
  9.       updateNum(num => num + 1) 
  10.     }} 
  11.   > 
  12.     { num } 
  13.   </div> 
  14.  
  15. export default App; 
  16. var dispatch = queue.dispatch = dispatchAction.bind( 
  17.   null, workInProgress, queue 
  18. // [num, updateNum] = useState(0) 
  19. return [hook.memoizedState, dispatch] 

調用 useState 的時候,返回的數組第二個參數為 dispatch,而 dispatch 由 dispatchAction bind 后得到。

  1. function dispatchAction(fiber, queue, action) { 
  2.   var update = { 
  3.     nextnull
  4.     actionaction
  5.     // 省略調度相關的參數... 
  6.   }; 
  7.  
  8.   var pending = queue.pending 
  9.   if (pending === null) { 
  10.     update.next = update 
  11.   } else { 
  12.     update.next = pending.next 
  13.     pending.next = update 
  14.   } 
  15.   queue.pending = update 
  16.  
  17.   // 執行更新 
  18.   scheduleUpdateOnFiber() 

可以看到這里構造鏈表的方式與 fiber.updateQueue 如出一轍。之前我們通過 updateNum 對 num 連續更新了 3 次,最后形成的更新隊列如下:

更新隊列

函數組件的更新

前面的文章分享過,Fiber 架構下的更新流程分為遞(beginWork)、歸(completeWork)兩個步驟,在 beginWork 中,會依據組件類型進行 render 操作構造子組件。

  1. function beginWork(current, workInProgress) { 
  2.   switch (workInProgress.tag) { 
  3.     // 其他類型組件代碼省略... 
  4.     case FunctionComponent: { 
  5.       // 這里的 type 就是函數組件的函數 
  6.       // 例如,前面的 App 組件,type 就是 function App() {} 
  7.       var Component = workInProgress.type 
  8.       var resolvedProps = workInProgress.pendingProps 
  9.       // 組件更新 
  10.       return updateFunctionComponent( 
  11.         current, workInProgress, Component, resolvedProps 
  12.       ) 
  13.     } 
  14.   } 
  15.  
  16. function updateFunctionComponent( 
  17.  current, workInProgress, Component, nextProps 
  18. ) { 
  19.   // 構造子組件 
  20.   var nextChildren = renderWithHooks( 
  21.     current, workInProgress, Component, nextProps 
  22.   ) 
  23.   reconcileChildren(current, workInProgress, nextChildren) 
  24.   return workInProgress.child 

看名字就能看出來,renderWithHooks 方法就是構造帶 Hooks 的子組件。

  1. function renderWithHooks( 
  2.  current, workInProgress, Component, props 
  3. ) { 
  4.   if (current !== null && current.memoizedState !== null) { 
  5.     ReactCurrentDispatcher.current = HooksDispatcherOnUpdate 
  6.   } else { 
  7.     ReactCurrentDispatcher.current = HooksDispatcherOnMount 
  8.   } 
  9.   var children = Component(props) 
  10.   return children 

從上面的代碼可以看出,函數組件更新或者首次渲染時,本質就是將函數取出執行了一遍。不同的地方在于給 ReactCurrentDispatcher 進行了不同的賦值,而 ReactCurrentDispatcher 的值最終會影響 useState 調用不同的方法。

根據之前文章講過的雙緩存機制,current 存在的時候表示是更新操作,不存在的時候表示首次渲染。

  1. function useState(initialState) { 
  2.   // 首次渲染時指向 HooksDispatcherOnMount 
  3.   // 更新操作時指向 HooksDispatcherOnUpdate 
  4.   var dispatcher = ReactCurrentDispatcher.current 
  5.   return dispatcher.useState(initialState) 

HooksDispatcherOnMount.useState 的代碼前面已經介紹過,這里不再著重介紹。

  1. // HooksDispatcherOnMount 的代碼前面已經介紹過 
  2. var HooksDispatcherOnMount = { 
  3.   useState: function (initialState) { 
  4.     return mountState(initialState) 
  5.   } 

我們重點看看 HooksDispatcherOnMount.useState 的邏輯。

  1. var HooksDispatcherOnUpdateInDEV = { 
  2.   useState: function (initialState) { 
  3.     return updateState() 
  4.   } 
  5.  
  6. function updateState() { 
  7.   // 取出當前 hook 
  8.   workInProgressHook = nextWorkInProgressHook 
  9.   nextWorkInProgressHook = workInProgressHook.next 
  10.  
  11.   var hook = nextWorkInProgressHook 
  12.   var queue = hook.queue 
  13.   var pendingQueue = queue.pending 
  14.  
  15.   // 處理更新 
  16.   var first = pendingQueue.next 
  17.   var state = hook.memoizedState 
  18.   var update = first 
  19.  
  20.   do { 
  21.     var action = update.action 
  22.     state = typeof action === 'function' ? action(state) : action 
  23.  
  24.     update = update.next
  25.   } while (update !== null && update !== first
  26.  
  27.  
  28.   hook.memoizedState = state 
  29.  
  30.   var dispatch = queue.dispatch 
  31.   return [hook.memoizedState, dispatch] 

如果有看之前的 setState 的代碼,這里的邏輯其實是一樣的。將更新對象的 action 取出,如果是函數就執行,如果不是函數就直接對 state 進行替換操作。

總結

React 系列的文章終于寫完了,這一篇文章應該是最簡單的一篇,如果想拋開 React 源碼,單獨看 Hooks 實現可以看這篇文章:《React Hooks 原理》。Fiber 架構為了能夠實現循環的方式更新,將所有涉及到數據的地方結構都改成了鏈表,這樣的優勢就是可以隨時中斷,為異步模式讓路,Fiber 樹就像一顆圣誕樹,上面掛滿了各種彩燈(alternate、EffectList、updateQueue、Hooks)。

本文轉載自微信公眾號「 更了不起的前端  」,可以通過以下二維碼關注。轉載本文請聯系更了不起的前端  公眾號。

 

責任編輯:武曉燕 來源: 更了不起的前端
相關推薦

2022-04-16 20:10:00

React Hookfiber框架

2020-09-24 08:45:10

React架構源碼

2020-10-13 08:36:30

React 架構機制

2020-09-30 09:15:24

React架構遞歸

2022-08-21 09:41:42

ReactVue3前端

2023-11-06 08:00:00

ReactJavaScript開發

2022-03-31 17:54:29

ReactHooks前端

2020-09-19 17:46:20

React Hooks開發函數

2024-06-04 14:17:26

2019-08-20 15:16:26

Reacthooks前端

2023-05-29 13:56:00

JSReact

2021-03-18 08:00:55

組件Hooks React

2022-02-10 19:15:18

React監聽系統模式

2021-05-11 08:48:23

React Hooks前端

2023-05-08 07:52:29

JSXReactHooks

2020-08-10 06:31:01

React Hooks前端開發

2022-03-16 22:24:50

ReactstateHooks

2021-11-05 10:36:19

性能優化實踐

2022-11-15 17:31:35

邊緣計算架構人工智能

2019-03-13 10:10:26

React組件前端
點贊
收藏

51CTO技術棧公眾號

99热99热| 激情自拍一区| 欧美日韩中文视频| 免费在线观看av网站| 国产一区久久久| 久久综合九色综合97婷婷女人 | 国产一区二区三区免费观看在线| 一区二区三区在线观看网站| 九色综合婷婷综合| 亚洲天堂网在线视频| 精品福利av| 最近2019中文字幕一页二页 | 中文字幕无码乱码人妻日韩精品| 欧美激情1区2区| 黄色日韩网站视频| 亚洲图片欧美午夜| 欧美日韩一区二区区| 在线毛片观看| 亚洲国产免费看| 中文字幕不卡三区| 欧美一区二区三区啪啪| 亚洲视频一区二区| 久久久久亚洲av无码专区喷水| 午夜精彩视频在线观看不卡| 最近2019年手机中文字幕| 欧美国产在线一区| av电影一区| 亚洲综合视频在线| 欧美日韩系列| 日本xxxx人| 国产专区欧美精品| 日韩av免费在线| 国产精品第九页| 欧美99久久| 日韩在线视频二区| av电影网站在线观看| 日韩电影不卡一区| 亚洲福利小视频| 美女被爆操网站| 97精品资源在线观看| 91国内精品野花午夜精品| 免费一级特黄毛片| 久草在线资源站资源站| 亚洲视频免费在线观看| 国产suv一区二区三区88区| 欧美成人久久| 欧美熟乱第一页| 国产毛片视频网站| 欧美另类tv| 亚洲美女区一区| 黄瓜视频免费观看在线观看www| 天天爽夜夜爽夜夜爽| 成人激情小说乱人伦| 成人欧美一区二区三区黑人免费| 国产精品无码一区二区桃花视频| 久久99精品国产91久久来源| 国产美女精品免费电影| 中文字幕人妻一区二区在线视频 | 热99这里只有精品| 波多野结衣在线观看| 亚洲一区二区三区四区在线免费观看| 黄色影视在线观看| 在线观看午夜av| 亚洲免费观看高清完整版在线 | 91精品国产自产在线观看永久| 免费又黄又爽又猛大片午夜| 日本不卡一区二区| 国产精品久久国产精品99gif| 免费黄色av片| 免费在线一区观看| 成人黄色av免费在线观看| 国产精品视频一区二区三区,| 国产一区二区三区免费观看| 999精品在线观看| 日本高清视频免费看| 久久久美女毛片 | 一区二区影院| 欧美激情在线视频二区| 少妇一级淫片免费放中国 | 久久人人妻人人人人妻性色av| 亚洲盗摄视频| 一夜七次郎国产精品亚洲| 四季av中文字幕| 亚洲欧美偷拍自拍| 91精品国产91久久久久福利| 国产日韩在线免费观看| 精品一区二区三区免费播放| 国产精品免费一区二区| 三级无遮挡在线观看| 亚洲男女自偷自拍| 日韩欧美在线视频观看| 免费黄色特级片| 99热一区二区| 成人精品一区二区三区校园激情 | 蜜桃传媒视频第一区入口在线看| 成a人片在线观看www视频| 国产精品不卡在线| 亚洲中文字幕无码av永久| 三级成人在线| 日韩一区二区三区四区| 久久国产精品无码一级毛片| 欧美激情欧美| 欧美夜福利tv在线| 国产又粗又猛又爽| 97超碰欧美中文字幕| 尤物一区二区三区| 麻豆网站免费在线观看| 9191久久久久久久久久久| chinese麻豆新拍video| 欧美hentaied在线观看| 97视频在线观看视频免费视频 | 国产一区二区三区视频在线| 亚洲精品国产品国语在线 | 午夜视频在线观看一区| 国产一伦一伦一伦| 久久夜色电影| 免费91麻豆精品国产自产在线观看 | 亚洲黄色小说网址| 国产精品欧美一级免费| 成人毛片视频网站| 91久久偷偷做嫩草影院电| 在线免费看av不卡| 精品免费囯产一区二区三区| 国产成人精品一区二区三区四区| 日韩中文字幕av在线| 男人av在线播放| 欧美一级久久久久久久大片| 中文字幕第二区| 久久激情婷婷| 久久天天狠狠| 国产99在线观看| 精品欧美久久久| 亚洲色图27p| 日韩福利视频导航| 欧美日韩高清免费| av今日在线| 亚洲国产欧美一区| 一级黄色免费在线观看| 麻豆一区产品精品蜜桃的特点| 日韩在线一区二区三区| 欧美不卡1区2区3区| av在线中出| 337p日本欧洲亚洲大胆精品| 精品欧美一区二区久久久久| 国模一区二区三区白浆| 中文字幕在线中文字幕日亚韩一区| 粉嫩av一区二区三区四区五区| 亚洲色图综合久久| 波多野结衣电影在线播放| 99r精品视频| 播放灌醉水嫩大学生国内精品| 国产精品网址| 5566日本婷婷色中文字幕97| 天天干天天草天天射| 欧美日韩激情小视频| 超碰男人的天堂| 亚洲在线国产日韩欧美| 久久综合一区| 日韩高清在线| 最近2019中文字幕第三页视频| 亚洲香蕉在线视频| 亚洲图片激情小说| 一区二区在线免费观看视频| 激情综合在线| 美日韩精品免费| 精品日本视频| xxxxx成人.com| 亚洲av综合色区无码一二三区| 亚洲综合色丁香婷婷六月图片| 99精品999| 亚洲欧洲一区二区天堂久久| 久久亚裔精品欧美| 91天天综合| 九九久久久久久久久激情| 殴美一级特黄aaaaaa| 欧美性精品220| 香蕉久久久久久久| 国产成人自拍网| 欧美国产激情视频| 久久一区91| 久久久噜噜噜久久狠狠50岁| 亚洲午夜av电影| 波多野结衣在线电影| 国产精品三级电影| 色欧美片视频在线观看在线视频| 久草免费资源站| 久久国产日本精品| 一区二区三区四区欧美日韩| 中文字幕一区二区三区日韩精品| 欧美性视频精品| 午夜视频在线观看免费视频| 精品久久久久久久一区二区蜜臀| 日韩一级在线视频| 亚洲男人的天堂在线aⅴ视频 | 成人一级视频在线观看| 精品国产成人av在线免| 欧美精品91| 日韩精品一区二区三区色偷偷 | 精品日韩欧美一区二区| 伦av综合一区| 一区二区三区在线免费视频| 女女互磨互喷水高潮les呻吟 | 麻豆91精品| 国产 国语对白 露脸| 欧美色图激情小说| 国产精品区二区三区日本| 国产精品传媒麻豆hd| 午夜精品久久久久久久99黑人| 欧美另类极品| 亚洲精品日韩久久久| 97超碰国产在线| 日韩欧美一区二区三区| 欧美国产精品一二三| 国产精品美女久久久久久久网站| 特级西西人体wwwww| 国产精品一区在线| 亚洲欧美国产中文| 久久福利影视| 日本国产在线播放| 欧美日本精品| 中文字幕av久久| 欧美午夜精彩| 人禽交欧美网站免费| 欧美爱爱网站| 国产高清一区视频| 视频一区在线| 91在线国产电影| 亚洲成人a级片| 国产欧美欧洲在线观看| 日日夜夜天天综合| 7777精品久久久久久| 丰满的护士2在线观看高清| 久久中文字幕一区| 天堂地址在线www| 色老头一区二区三区在线观看| 激情在线视频| 亚洲欧美中文字幕在线一区| 午夜影院免费体验区| 亚洲精品成人网| 午夜成人鲁丝片午夜精品| 欧美精品一区二区蜜臀亚洲| 国精品人妻无码一区二区三区喝尿 | 亚洲天堂免费在线| 欧美专区日韩视频| 欧美精品自拍视频| 中文在线综合| 96久久精品| av网站免费大全| 亚洲国产美女搞黄色| 免看一级a毛片一片成人不卡| 亚洲色图欧美激情| 亚洲欧美精品aaaaaa片| 综合在线观看色| 欧美成人片在线观看| 免费不卡中文字幕在线| 国产精品爽爽ⅴa在线观看| 日韩毛片免费观看| 国产精品高潮呻吟久久av无限| 三级成人在线| 国产美女被下药99| 免费在线观看一区| 欧美亚洲三级| 亚洲成av人片| 国产精品高潮呻吟久久av野狼| 中文字幕第36页| 综合久久av| 91在线观看免费观看| 玖玖玖电影综合影院| 福利视频久久| 天天躁日日躁狠狠躁欧美巨大小说| 六十路精品视频| 欧美在线观看视频一区| 免费看啪啪网站| 一区免费在线| 久久精品国产99国产精品澳门| 高h震动喷水双性1v1| 亚洲第一精品夜夜躁人人躁| 成人欧美一区二区三区在线湿哒哒| 四虎影视精品成人| 亚洲视频777| 国产黄色在线网站| 午夜精品久久久久久99热软件| 欧美大片免费观看网址| 成人h视频在线| 久久午夜影院| 亚洲精品乱码久久久久久蜜桃91| 亚洲欧美偷拍自拍| 日本三级免费网站| 精品一区免费av| 久久福利小视频| 国产精品天干天干在线综合| 国产亚洲小视频| 欧美中文字幕不卡| 亚洲精品人妻无码| 亚洲无线码在线一区观看| 在线āv视频| 国产精品女人久久久久久| 1204国产成人精品视频| 欧美日韩一区二| 欧美日韩福利| 天堂视频免费看| 91免费看视频| 国产大学生自拍| 欧美色图在线观看| 神马午夜在线观看| 久久影院中文字幕| 欧美黑人一区| 国产一区二区三区无遮挡| 欧美韩日一区| 麻豆传传媒久久久爱| 成人免费看黄yyy456| 免费成人深夜夜行网站| 色久优优欧美色久优优| 蜜臀av在线观看| 不卡av在线播放| 日韩毛片网站| 日韩精品伦理第一区| 亚洲精品一级| 免费黄色在线播放| 中文字幕综合网| 中文字幕在线播出| 亚洲人成电影网站色www| 超碰在线cao| 国产精品免费一区二区三区在线观看 | 午夜久久久久久久久| 97精品人妻一区二区三区| 夜夜嗨av一区二区三区四区| 一根才成人网| 久久天天狠狠| 国产精品免费看| 老熟妇精品一区二区三区| 亚洲一区av在线| 草草视频在线播放| 久久国产精品视频| 2019中文亚洲字幕| 一卡二卡3卡四卡高清精品视频| 久久综合亚州| 中文字幕网站在线观看| 色综合久久综合中文综合网| 蜜桃视频在线观看网站| 茄子视频成人在线| 天堂综合网久久| 妺妺窝人体色www在线小说| 成人av在线影院| 日韩精品一区二区av| 亚洲国产精品资源| 超碰在线99| 欧美三级电影在线播放| 久久久久在线| 亚洲天堂精品一区| 4hu四虎永久在线影院成人| 黄色av电影在线观看| 91久久久久久| 精品成人在线| 国产三级国产精品| 色8久久人人97超碰香蕉987| 美国一级片在线免费观看视频 | 精品国产三区在线| 黑人巨大国产9丨视频| 国产xxx精品视频大全| 九九九国产视频| 精品伊人久久97| jizz免费一区二区三区| 一本一道久久久a久久久精品91| 精品一区二区在线视频| www青青草原| 亚洲国产精品yw在线观看| 日韩精品美女| 小说区图片区图片区另类灬| 国产在线乱码一区二区三区| 精品在线免费观看视频| 日韩精品视频在线播放| 色香欲www7777综合网| 国产日本欧美在线| 成人午夜视频网站| 色屁屁影院www国产高清麻豆| 中文字幕亚洲综合久久| 亚洲综合网狠久久| 国产xxxxx在线观看| 中文字幕亚洲成人| 熟妇人妻一区二区三区四区| 国产精品成人av在线| 综合久久99| 香蕉视频黄色在线观看| 欧美美女视频在线观看| 国产亚av手机在线观看| 视频一区视频二区视频| 国产成人亚洲综合a∨婷婷图片| 免费在线不卡视频| 中文字幕日韩欧美| 国内精品免费| www.日本一区| 午夜精品一区在线观看| 91大神xh98hx在线播放| 99re在线视频上| 日韩电影在线观看电影| 精品无码人妻一区二区三区| 在线色欧美三级视频| swag国产精品一区二区| 三级a三级三级三级a十八发禁止|