useMemo與useCallback使用指南

2022-02-23 15:26:33 字數 2861 閱讀 4477

在介紹一下這兩個hooks的作用之前,我們先來回顧一下react中的效能優化。在hooks誕生之前,如果元件包含內部state,我們都是基於class的形式來建立元件。當時我們也知道,react中,效能的優化點在於:

呼叫setstate,就會觸發元件的重新渲染,無論前後的state是否不同

父元件更新,子元件也會自動的更新

基於上面的兩點,我們通常的解決方案是:使用immutable進行比較,在不相等的時候呼叫setstate;在shouldcomponentupdate中判斷前後的props和state,如果沒有變化,則返回false來阻止更新。

在hooks出來之後,我們能夠使用function的形式來建立包含內部state的元件。但是,使用function的形式,失去了上面的shouldcomponentupdate,我們無法通過判斷前後狀態來決定是否更新。而且,在函式元件中,react不再區分mount和update兩個狀態,這意味著函式元件的每一次呼叫都會執行其內部的所有邏輯,那麼會帶來較大的效能損耗。因此usememo 和usecallback就是解決效能問題的殺手鐗。

我們先簡單的看一下usememo和usecallback的呼叫簽名:

function usememo(factory: () => t, deps: dependencylist | undefined): t; function usecallbackany>(callback: t, deps: dependencylist): t;
usecallback和usememo的引數跟useeffect一致,他們之間最大的區別有是useeffect會用於處理***,而前兩個hooks不能。

usememo和usecallback都會在元件第一次渲染的時候執行,之後會在其依賴的變數發生改變時再次執行;並且這兩個hooks都返回快取的值,usememo返回快取的變數,usecallback返回快取的函式。

我們來看乙個反例:

import react from 'react';

export default function withoutmemo()

return sum;

}return

--h4>

+c1button>

div>

div>;

}這裡建立了兩個state,然後通過expensive函式,執行一次昂貴的計算,拿到count對應的某個值。我們可以看到:無論是修改count還是val,由於元件的重新渲染,都會觸發expensive的執行(能夠在控制台看到,即使修改val,也會列印);但是這裡的昂貴計算只依賴於count的值,在val修改的時候,是沒有必要再次計算的。在這種情況下,我們就可以使用usememo,只在count的值修改時,執行expensive計算:

export default function withmemo()

return sum;

}, [count]);

return

-h4>

+c1button>

div>

div>;

}上面我們可以看到,使用usememo來執行昂貴的計算,然後將計算值返回,並且將count作為依賴值傳遞進去。這樣,就只會在count改變的時候觸發expensive執行,在修改val的時候,返回上一次快取的值。

講完了usememo,接下來是usecallback。usecallback跟usememo比較類似,但它返回的是快取的函式。我們看一下最簡單的用法:

const fna = usecallback(fnb, [a])
上面的usecallback會將我們傳遞給它的函式fnb返回,並且將這個結果快取;當依賴a變更時,會返回新的函式。既然返回的是函式,我們無法很好的判斷返回的函式是否變更,所以我們可以借助es6新增的資料型別set來判斷,具體如下:

import react, from 'react';

const set = new set();

export default function callback() , [count]);

set.add(callback);

return

h4>

h4>

+button>

div>

div>;

}我們可以看到,每次修改count,set.size就會+1,這說明usecallback依賴變數count,count變更時會返回新的函式;而val變更時,set.size不會變,說明返回的是快取的舊版本函式。

知道usecallback有什麼樣的特點,那有什麼作用呢?

使用場景是:有乙個父元件,其中包含子元件,子元件接收乙個函式作為props;通常而言,如果父元件更新了,子元件也會執行更新;但是大多數場景下,更新是沒有必要的,我們可以借助usecallback來返回函式,然後把這個函式作為props傳遞給子元件;這樣,子元件就能避免不必要的更新。

import react, from 'react';

function parent() , [count]);

return

h4>

+button>

div>

div>;

}function child() , [callback]);

return

div>

}不僅是上面的例子,所有依賴本地狀態或props來建立函式,需要使用到快取函式的地方,都是usecallback的應用場景。

useeffect、usememo、usecallback都是自帶閉包的。也就是說,每一次元件的渲染,其都會捕獲當前元件函式上下文中的狀態(state, props),所以每一次這三種hooks的執行,反映的也都是當前的狀態,你無法使用它們來捕獲上一次的狀態。對於這種情況,我們應該使用ref來訪問。

源**:

原文

useCallback和useMemo用法區別

1.usecallback 作用 在依賴項發生變化的時候,返回乙個新的函式引用。需求 1 請求資料的介面需要放在useeffect外面,因為要將該方法傳遞給子元件 2 在conditions發生變化時,自動執行該函式 3 只有在conditions發生變化時,才會重新render子元件中的內容。如下...

useMemo和useCallback的區別和使用

usememo const memoizedvalue usememo computeexpensivevalue a,b a,b 將 建立 函式和依賴項新增到引數上使用備註,它僅會在某個依賴項改變時才重新計算備忘錄值。這種優化避免在每次渲染時都進行高開銷的計算。也就是說usememo可以讓函式在某...

SQL與NoSQL MySQL與NoSQL的融合

寫這一篇內容的原因是mysql5.6.2突然推出了memcached的功能。nosql to innodb with memcached的出現,可以看出nosql對關聯式資料庫的確產生了巨大的影響,個人覺得這是乙個非常大的進步,可以讓開發人員更加方便的使用nosql和關聯式資料庫。nosql一般被認...