如何使用useMemo

本篇內(nèi)容主要講解“如何使用useMemo”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“如何使用useMemo”吧!

創(chuàng)新互聯(lián)專注于古田網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供古田營(yíng)銷型網(wǎng)站建設(shè),古田網(wǎng)站制作、古田網(wǎng)頁(yè)設(shè)計(jì)、古田網(wǎng)站官網(wǎng)定制、成都小程序開發(fā)服務(wù),打造古田網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供古田網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。

作為「性能優(yōu)化」手段,一般用useMemo緩存函數(shù)組件中比較消耗性能的計(jì)算結(jié)果:

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

只有在依賴項(xiàng)改變后才會(huì)重新計(jì)算新的memoizedValue。

你有沒有想過(guò),如果用useMemo緩存函數(shù)組件的返回值,會(huì)怎么樣呢?

舉個(gè)例子

我們有個(gè)全局context —— AppContext。

由于同學(xué)們偷懶,隨著項(xiàng)目的迭代,新增的context都選擇放在AppContext里,導(dǎo)致AppContext包含的內(nèi)容越來(lái)越多。

現(xiàn)在我們有個(gè)Tree組件,他會(huì)渲染一個(gè)很耗性能的大組件ExpensiveTree。

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

該組件內(nèi)部依賴AppContext中的theme狀態(tài)。

由于AppContext中包含很多與theme無(wú)關(guān)的state,導(dǎo)致每次其他無(wú)關(guān)的state更新,Tree都會(huì)重新render,進(jìn)而ExpensiveTree組件也重新render。

現(xiàn)在這個(gè)優(yōu)化任務(wù)交到了你手上,該怎么辦呢?

優(yōu)化ExpensiveTree

這時(shí)候,useMemo就能派上用場(chǎng):

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

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

這樣,即使AppContext改變導(dǎo)致Tree反復(fù)render,ExpensiveTree也只會(huì)在theme改變后render。

原理解析

要理解這么做有效的原因,需要了解三點(diǎn):

  1. useMemo返回值是什么

  2. 函數(shù)組件的返回值是什么

  3. React組件在什么時(shí)候render

回答第一個(gè)問(wèn)題:useMemo會(huì)將第一個(gè)參數(shù)(函數(shù))的返回值保存在組件對(duì)應(yīng)fiber中,只有在依賴項(xiàng)(第二個(gè)參數(shù))變化后才會(huì)重新調(diào)用第一個(gè)參數(shù)(函數(shù))計(jì)算一個(gè)新值。

回答第二個(gè)問(wèn)題:函數(shù)組件的返回值是JSX對(duì)象。

同一個(gè)函數(shù)組件調(diào)用多次,返回的是多個(gè)「不同」的JSX對(duì)象(即使props未變,但JSX是新的引用)。

按照以上兩個(gè)回答,我們可以得出結(jié)論:

  • 以上useMemo用法實(shí)際上在函數(shù)組件對(duì)應(yīng)的fiber中緩存了一個(gè)完整的JSX對(duì)象

第三個(gè)問(wèn)題,函數(shù)組件需要同時(shí)滿足如下條件才不會(huì)render:

1 oldProps === newProps

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

2 組件context沒有變化

3 workInProgress.type === current.type

組件更新前后fiber.type未變化,比如div沒有變?yōu)閜。

4 !includesSomeLane(renderLanes, updateLanes)

當(dāng)前fiber上不存在更新,或者存在更新但優(yōu)先級(jí)低。

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

當(dāng)我們不使用useMemo包裹返回值,每次Tree render返回的都是全新的JSX對(duì)象。

所以對(duì)于ExpensiveTree,oldProps !== newProps。

再看2:ExpensiveTree內(nèi)部context沒變,滿足

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

再看4: ExpensiveTree內(nèi)沒有狀態(tài)更新,滿足

所以,當(dāng)我們使用useMemo包裹ExpensiveTree后,當(dāng)theme不變,每次Treerender后返回的都是同一個(gè)JSX對(duì)象,滿足第一條。

基于這個(gè)原因,ExpensiveTree不會(huì)render。

到此,相信大家對(duì)“如何使用useMemo”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

網(wǎng)站名稱:如何使用useMemo
文章轉(zhuǎn)載:http://bm7419.com/article0/jdidio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)、網(wǎng)站策劃、網(wǎng)站營(yíng)銷網(wǎng)站內(nèi)鏈、ChatGPT、網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作