React中useMemo 和 useCallback 的區(qū)別小結
前言
剛開始學習 React Hooks 時,我一直分不清 useMemo 和 useCallback。
因為它們長得非常像:
const value = useMemo(() => {
return result
}, [])
const fn = useCallback(() => {
console.log("hello")
}, [])
甚至依賴數(shù)組的寫法都一樣。
學習了一段時間后,我發(fā)現(xiàn):
useMemo 緩存的是“值”,useCallback 緩存的是“函數(shù)”。
這是兩者最核心的區(qū)別。
什么是 useMemo
useMemo 用于緩存計算結果。
語法:
const memoizedValue = useMemo(() => {
return compute()
}, [deps])
例如:
const total = useMemo(() => {
console.log("執(zhí)行計算")
return price * count
}, [price, count])
當:
price count
沒有變化時,
React 不會再次執(zhí)行計算邏輯。
直接返回上一次緩存結果。
useMemo 解決什么問題
假設有一個商品列表:
const products = [...]
需要篩選:
const filteredProducts = products.filter(...)
如果組件頻繁重新渲染:
setInputValue(...)
即使商品數(shù)據(jù)沒變化,
filter 也會不斷執(zhí)行。
這時可以使用:
const filteredProducts = useMemo(() => {
return products.filter(...)
}, [products])
避免重復計算。
什么是 useCallback
useCallback 用于緩存函數(shù)。
語法:
const memoizedFn = useCallback(() => {
...
}, [deps])
例如:
const handleClick = useCallback(() => {
console.log("點擊")
}, [])
依賴不變時,
返回同一個函數(shù)引用。
useCallback 解決什么問題
React 每次渲染時:
function App() {
const handleClick = () => {}
return <Child onClick={handleClick} />
}
實際上:
handleClick
會被重新創(chuàng)建。
即:
舊函數(shù) !== 新函數(shù)
如果:
Child
使用了:
React.memo
那么仍然會重新渲染。
因為:
props變化了
此時可以使用:
const handleClick = useCallback(() => {}, [])
讓函數(shù)引用保持不變。
最簡單的記憶方法
記住一句話:
useMemo 緩存結果 useCallback 緩存函數(shù)
例如:
const total = useMemo(() => {
return price * count
}, [price, count])
緩存的是:
100 200 300
這些計算結果。
const handleClick = useCallback(() => {
console.log("hello")
}, [])
緩存的是:
function
本身。
Vue 開發(fā)者如何理解
如果你是 Vue 開發(fā)者。
可以這樣記:
useMemo
類似:
computed
const total = computed(() => {
return price.value * count.value
})
緩存計算結果。
useCallback
Vue 中沒有完全對應概念。
因為 Vue 模板編譯階段已經做了很多優(yōu)化。
React 更關注:
函數(shù)引用是否變化
所以才有 useCallback。
useMemo 和 useCallback 對比
| 對比項 | useMemo | useCallback |
|---|---|---|
| 緩存內容 | 值 | 函數(shù) |
| 返回值 | 計算結果 | 函數(shù) |
| 常見場景 | 大數(shù)據(jù)計算 | 傳遞事件函數(shù) |
| 對應Vue | computed | 無明顯對應 |
一個常見誤區(qū)
很多初學者會這樣寫:
const handleClick = useCallback(() => {
console.log("hello")
}, [])
整個項目到處都是:
useCallback
實際上:
這樣并不一定提升性能。
因為:
useCallback 本身也有維護成本。
React 需要:
- 保存緩存
- 對比依賴
如果函數(shù)很簡單:
() => console.log("hello")
完全沒必要使用。
什么時候應該使用
推薦使用場景:
useMemo
- 大量數(shù)據(jù)計算
- 排序
- 過濾
- 聚合統(tǒng)計
例如:
1000+ 10000+
條數(shù)據(jù)處理。
useCallback
- 傳遞給子組件
- React.memo 配合使用
- 自定義 Hook 返回函數(shù)
例如:
<Child onClick={handleClick} />
面試回答模板
如果面試官問:
“useMemo 和 useCallback 的區(qū)別是什么?”
我會這樣回答:
useMemo 用于緩存計算結果,返回的是一個值;useCallback 用于緩存函數(shù),返回的是一個函數(shù)引用。兩者都依賴依賴數(shù)組控制是否重新生成。通常 useMemo 用于優(yōu)化復雜計算,useCallback 用于避免函數(shù)重復創(chuàng)建,尤其是在 React.memo 場景下減少子組件不必要渲染。
總結
一句話記憶:
useMemo:
緩存計算結果。
useCallback:
緩存函數(shù)引用。
不要為了優(yōu)化而優(yōu)化,只有在組件存在實際性能問題時,再合理使用它們。
到此這篇關于React中useMemo 和 useCallback 的區(qū)別小結的文章就介紹到這了,更多相關React useMemo 和 useCallback區(qū)別內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- 源碼分析React中useCallback和useMemo
- React中useMemo和useCallback的使用小結
- React中useMemo、useCallback的具體使用
- 詳解React中的useMemo和useCallback的區(qū)別
- React中useCallback useMemo使用方法快速精通
- React中useCallback useMemo到底該怎么用
- 解析React中useMemo與useCallback的區(qū)別
- react性能優(yōu)化useMemo與useCallback使用對比詳解
- react組件memo useMemo useCallback使用區(qū)別示例
- React useMemo和useCallback的使用場景

