中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用useMemo

發布時間:2021-10-19 13:53:35 來源:億速云 閱讀:240 作者:iii 欄目:web開發

本篇內容主要講解“如何使用useMemo”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何使用useMemo”吧!

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

function App() {   const memoizedValue = useMemo(     () => computeExpensiveValue(a, b),     [a, b]   );   // ... }

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

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

舉個例子

我們有個全局context —— AppContext。

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

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

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

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

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

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

優化ExpensiveTree

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

function Tree() {   let appContextValue = useContext(AppContext);   let theme = appContextValue.theme;    return useMemo(() => {     return <ExpensiveTree className={theme} />;   }, [theme]) }

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

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

原理解析

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

  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”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

淳化县| 榆树市| 政和县| 河间市| 阜新| 东乌珠穆沁旗| 合肥市| 双牌县| 平舆县| 洛隆县| 普安县| 文山县| 民县| 莱阳市| 铜陵市| 通州区| 新绛县| 长兴县| 甘泉县| 漳州市| 西平县| 左云县| 娄底市| 淳化县| 桐庐县| 同德县| 集安市| 都江堰市| 塘沽区| 纳雍县| 曲松县| 玉田县| 台安县| 如皋市| 宜丰县| 星子县| 兴义市| 贡嘎县| 民乐县| 若尔盖县| 永顺县|