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

奇怪的useMemo知識增加了

開發 前端
這篇文章提到的useMemo用法,相比Vue,React更靈活,開發過程中需要開發者注意更多細節。要完全了解React,可能需要學習一些源碼層面的知識。

[[380079]]

 作為「性能優化」手段,一般用useMemo緩存函數組件中比較消耗性能的計算結果:

  1. function App() { 
  2.   const memoizedValue = useMemo( 
  3.     () => computeExpensiveValue(a, b), 
  4.     [a, b] 
  5.   ); 
  6.   // ... 

只有在依賴項改變后才會重新計算新的memoizedValue。

你有沒有想過,如果用useMemo緩存函數組件的返回值,會怎么樣呢?

舉個例子

我們有個全局context —— AppContext。

由于同學們偷懶,隨著項目的迭代,新增的context都選擇放在AppContext里,導致AppContext包含的內容越來越多。

現在我們有個Tree組件,他會渲染一個很耗性能的大組件ExpensiveTree。

  1. function Tree() { 
  2.   let appContextValue = useContext(AppContext); 
  3.   let theme = appContextValue.theme; 
  4.  
  5.   return <ExpensiveTree className={theme} />; 

該組件內部依賴AppContext中的theme狀態。

由于AppContext中包含很多與theme無關的state,導致每次其他無關的state更新,Tree都會重新render,進而ExpensiveTree組件也重新render。

現在這個優化任務交到了你手上,該怎么辦呢?

優化ExpensiveTree

這時候,useMemo就能派上用場:

  1. function Tree() { 
  2.   let appContextValue = useContext(AppContext); 
  3.   let theme = appContextValue.theme; 
  4.  
  5.   return useMemo(() => { 
  6.     return <ExpensiveTree className={theme} />; 
  7.   }, [theme]) 

我們將返回的ExpensiveTree作為useMemo返回值,theme作為依賴。

這樣,即使AppContext改變導致Tree反復render,ExpensiveTree也只會在theme改變后render。

[[380080]]

原理解析

要理解這么做有效的原因,需要了解三點:

  1. useMemo返回值是什么
  2. 函數組件的返回值是什么
  3. React組件在什么時候render

回答第一個問題:useMemo會將第一個參數(函數)的返回值保存在組件對應fiber中,只有在依賴項(第二個參數)變化后才會重新調用第一個參數(函數)計算一個新值。

回答第二個問題:函數組件的返回值是JSX對象。

同一個函數組件調用多次,返回的是多個「不同」的JSX對象(即使props未變,但JSX是新的引用)。

按照以上兩個回答,我們可以得出結論:

  • 以上useMemo用法實際上在函數組件對應的fiber中緩存了一個完整的JSX對象

第三個問題,函數組件需要同時滿足如下條件才不會render:

1 oldProps === newProps

前后兩次更新props全等,注意是「全等」。

2 組件context沒有變化

3 workInProgress.type === current.type

組件更新前后fiber.type未變化,比如div沒有變為p。

4 !includesSomeLane(renderLanes, updateLanes)

當前fiber上不存在更新,或者存在更新但優先級低。

  • 更詳細的解釋,可以參考這篇文章:React組件到底什么時候render?

當我們不使用useMemo包裹返回值,每次Tree render返回的都是全新的JSX對象。

所以對于ExpensiveTree,oldProps !== newProps。

再看2:ExpensiveTree內部context沒變,滿足

再看3:ExpensiveTree更新前后type都是ExpensiveTree,滿足

再看4: ExpensiveTree內沒有狀態更新,滿足

所以,當我們使用useMemo包裹ExpensiveTree后,當theme不變,每次Treerender后返回的都是同一個JSX對象,滿足第一條。

基于這個原因,ExpensiveTree不會render。

總結

這篇文章提到的useMemo用法,并未在官網文檔中體現,而是在#15156[1]中由Dan介紹。

相比Vue,React更靈活,開發過程中需要開發者注意更多細節。要完全了解React,可能需要學習一些源碼層面的知識。

參考資料

[1]#15156:

https://github.com/facebook/react/issues/15156#issuecomment-474590693

 

責任編輯:姜華 來源: 魔術師卡頌
相關推薦

2021-10-09 09:35:28

開發JavaScript 代碼

2010-10-19 11:30:16

IT培訓

2021-02-22 10:23:01

程序員技能開發者

2009-06-11 17:18:23

EJB3.1Singleton B

2023-01-16 18:22:53

Discourse開源

2012-04-30 20:44:55

2022-02-10 10:52:09

網絡攻擊網絡安全漏洞

2015-10-19 17:36:19

MOST內核Linux

2023-05-21 23:40:03

開源圖文模型

2020-12-29 09:37:41

漏洞網絡安全網絡攻擊

2020-05-15 19:25:09

HTML5JavaScript前端

2023-10-04 09:38:55

Firefox瀏覽器

2022-05-30 16:19:40

惡意軟件僵尸網絡網絡攻擊

2009-01-12 16:25:40

電子郵件數據管理法規遵從

2023-12-15 14:57:39

ReactNativeFabric

2022-11-04 12:27:35

2021-03-18 08:03:58

SteamMesa緩存

2018-07-11 04:16:16

2022-08-08 10:42:39

物聯網物聯網技術

2018-09-25 10:46:15

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久久久久久久爱 | 久久久久久国产精品免费免费男同 | 日本久久久一区二区三区 | 一级免费毛片 | 91久久久久久久 | 成人免费网站 | 欧美一区二区视频 | 国产精品久久久久久久7电影 | 亚洲 欧美 日韩在线 | 色婷婷综合久久久中文字幕 | 视频一区二区在线观看 | 亚洲免费人成在线视频观看 | 久久久精| 欧美精品综合 | av在线免费观看不卡 | 日韩三级在线 | 欧美一区二区三区视频 | 天堂国产 | 日本h片在线观看 | 国产中文字幕亚洲 | 久久九九色 | 国产午夜精品一区二区三区 | 麻豆av片| 91精品国产自产精品男人的天堂 | 天天看天天干 | 日本视频在线播放 | 啪啪av| 午夜精品久久久久久久星辰影院 | 精品无码三级在线观看视频 | 午夜免费视频 | 七七婷婷婷婷精品国产 | 国产在线精品一区二区三区 | 亚洲精品免费在线观看 | 看片地址 | 黄色一级电影在线观看 | 国产极品车模吞精高潮呻吟 | 国产99在线 | 欧美 | 成人不卡视频 | 国产粉嫩尤物极品99综合精品 | 草久久| 亚洲国产精品va在线看黑人 |