![](/img/trans.png)
[英]When to use useMemo and useCallback for performance optimization?
[英]useCallback vs. useMemo and when to use them
useCallback
和useMemo
之間的主要區別是什么? 什么時候使用 React Hooks 的useCallback
?
useMemo(() => (bar) => foo + bar, [foo]);
使用 useCallback 的等效代碼:
useCallback((bar) => foo + bar, [foo]);
使用回調只是useMemo
與函數一起使用的速記變體。
這就是它存在的原因:當您使用useMemo
,該值通常會在其依賴項之一發生變化時發生變化。 例如:
const fullName = useMemo(() => firstName + lastName, [firstName, lastName]);
如果firstName
或lastName
更改, fullName
也會更改。 另一方面,函數本身通常不需要重新計算,它們的依賴關系大多是可能會改變的閉包值。
const getFullName = useCallback(() => firstName + lastName, [firstName, lastName]);
在這里,當firstName
或lastName
更改時,我們不需要具有不同主體的完全不同的函數,但我們確實需要具有相同函數的新實例,以便它在閉包中具有最新值(依賴項) . 所以 React 團隊只是為了方便起見添加了它,因為它是一個常見的用例,而且() => () =>
語法有點難看。
useMemo
和useCallback
都使用一種叫做記憶化,你可以像鈎子記起了想起來了。
區別:
useMemo
將記住/記住您傳遞給它的函數返回的值,直到依賴關系發生變化。
const num = 10
const result = useMemo(() => num + num, [num])
// result is now equal to 20
useCallback
會記住/記住你傳遞給它的實際函數,直到依賴關系發生變化,這會給你一些稱為引用相等的東西。
const num = 10
const result = useCallback(() => num + num, [num])
// result is now equal to () => num + num.
// result === result between renders.
參照平等:
() => {} === () => {} // This is false
const a = () => {}
a === a // This is true
它們都將一個函數和一個依賴項數組作為參數,如'useEffect'。 只有在其中一個依賴項值發生更改時,才會更改函數的返回值 - 否則將返回緩存的值。
請注意,傳遞一個空的依賴數組或根本沒有數組將導致Hook在每次調用時返回一個memoized值。
兩者之間的主要區別在於'useCallback'返回一個memoized回調,'useMemo'返回一個memoized值,該值是函數參數的結果。
如果你必須處理大量數據,'useMemo'是完美的Hook,因為它將在第一次渲染時完成一次工作,然后在每個其他渲染上返回一個緩存版本。
但是,'useCallback'的使用方式不同。 例如,經常重新渲染的父組件。 在父級內部,我們有一個帶有函數prop的子組件。 在每次重新渲染時,Child將無用地重新執行其函數prop。 但是,如果將'useCallback'作為具有依賴關系數組的prop傳遞,它將解決該問題,因為該函數僅在依賴關系更改時才會執行。 然后每個其他重新渲染都將獲得一個緩存函數。
import React, { useState, useMemo, useCallback } from "react";
const App = () => {
// We create two states that will keep count of the number of time all hooks are called
const [callbackCount, setCallbackCount] = useState(0);
const [memoCount, setMemoCount] = useState(0);
const memoFunction = () => {
console.log(memoCount, "memo called");
// Do something that will take a lot of processing ...
};
// Here if we give an empty array of dependencies, the callback function will return the old value of callbackCount
// because useCallback will return its memoized version
const callbackFunction = useCallback(() => {
console.log(callbackCount, "callback called");
// Do something with callbackCount ...
return callbackCount;
}, [callbackCount]);
// We create the memo hook, when memoCount changes, the function will be executed again
useMemo(memoFunction, [memoCount]);
return (
<>
{/* This component will receive a function that will change when the dependency value changes */}
<ChildComponent action={callbackFunction} />
{/* Change the callback hook dependency to trigger a change in the child */}
<button onClick={() => setCallbackCount(callbackCount + 1)}>
Change callback count
</button>
{/* After creating useMemo, each change of memoCount will trigger the function passed to the hook,
otherwise the memoized value will be returned */}
<button onClick={() => setMemoCount(memoCount + 1)}>
Change memo count
</button>
</>
);
};
const ChildComponent = ({action}) => {
const [value, setValue] = useState(0)
useEffect(() => {
let val = action()
setValue(val)
}, [action])
return(
<>
Child : {value}
</>
)
}
現在,您已准備好使用React Hooks優化代碼。 回顧一下:你不應該使用'useCallback'和'useMemo'來做所有事情。 'useMemo'應該用於大數據處理,而'useCallback'是一種向代碼添加更多依賴的方法,以避免無用的渲染。
我們可以使用useCallback
來useCallback
一個函數,這意味着這個函數只有在依賴數組中的任何依賴發生變化時才會被重新定義。
useMemo(() => computation(a, b), [a, b])
是讓我們記住昂貴計算的鈎子。 給定相同的 [a, b] 依賴項,一旦記憶,鈎子將返回記憶值而不調用計算(a,b)。
本文介紹了不同的 React Memoization 方法:React.memo、useMemo、useCallback,它們之間有什么不同並附有實際示例: https ://medium.com/geekculture/great-confusion-about-react-memoization-methods-react-memo -usememo-usecallback-a10ebdd3a316
useMemo 用於記憶值,React.memo 用於包裝 React Function 組件以防止重新渲染。 useCallback 用於記憶函數。
useMemo
有助於防止重新渲染,除非對函數的依賴項已更改,而useCallback
有助於防止重新渲染,除非函數已更改。 即當一個函數作為參數傳遞給另一個函數時, useCallback
將只允許在傳遞不同的函數后重新渲染。 這是一個資源的鏈接,可能有助於進一步解釋
https://btholt.github.io/complete-intro-to-react-v5/hooks-in-depth
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.