簡述:
Returns a memoized value. 也就是 dependencies 沒有改變的情況下,
把某個運算的值保存下來 ( 這個 slowFunction 回傳值可以是 object、array、basic type),
主要目的用來「避免重複進行複雜耗時的計算」,因此為了避免在每一次 re-render 都重新運算,
可以用 useMemo 來記住這個函式的運算結果,並在下一次 re-render 階段,
透過判斷 dependency array 是否有變化來判斷是否重新運算函式,
如果 dependency array 不變就回傳上一次的運算結果。
使用方式:
//第一個參數傳入要記住的運算函式,第二個參數傳入 dependency array。
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b])
簡述:
Returns a memoized callback. 也就是 dependencies 沒有改變的情況下,
把某個 function 保存下來,主要目的是避免在 component 內部宣告的 function
因為每一次 re-render 時 function 都會分配到一個新的記憶體位址,useCallback
可以記憶住該 function 的記憶體位置,避免每一次子元件 re-render 時,
都因為 function 的記憶體位置改變導致子元件重新渲染。
使用方式:
//將要記住記憶體位置的 function 用 useCallback 包住並傳入 dependency array 當作第二個參數。
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
const tags = useMemo(() => {
return ['happy', 'sad', 'madness'];
}, []);
console.log('This is what useMemo looks like: ', tags);
const contentHandler = useCallback(() => {
return `I did ${count} times in my current job.`;
}, [count]);
console.log('This is what useCallback looks like: ', contentHandler);
區分兩者最大的不同在於
輸出之後會變成
本身運用useMemo & useCallBack主軸都是為了效能優化,但優化的同時總是會帶來額外的成本消耗,所以運用的同時可能就需要評估一下是否合適。
如果只是使用在簡易的計算上反而沒有使用的必要
// Assume this returns an Array of 3000 records
const menuItemRows = useMemo(
() => thousandsOfMenuItems.map(menuItem => (
<MenuItemRow key={menuItem.uuid} name={menuItem.name} />
)),
[thousandsOfMenuItems]
);
// When your callback are used in multiple useEffect()
function SearchResults({ query }) {
const getFetchUrl = useCallback(() => {
return 'https://hn.algolia.com/api/v1/search?query=' + query;
}, [query]);
useEffect(() => {
const url = getFetchUrl('react');
// ... Fetch data and do something ...
}, [getFetchUrl]);
useEffect(() => {
const url = getFetchUrl('redux');
// ... Fetch data and do something ...
}, [getFetchUrl]);
// ...
}
useMemo & useCallBack大量使用也可能造成額外的效能問題,因此建議的使用情境如下: