喂!我是 Wei

Front-End Engineer

Be a Problem Solver.

⌘K

導覽

所有文章緣起互動小功能

文章分類

目錄
useMemo 是什麼?useCallback 是什麼?useMemo / useCallback 差異React.memo 又是什麼?什麼時候不該用?常見追問useMemo 可以避免 component re-render 嗎?dependency array 寫錯會怎樣?useCallback 會讓函式不被建立嗎?面試回答模板

相關文章

前端工程師面試題:React Key 為什麼重要?useEffect dependency array 為什麼重要?

2026年6月7日

前端工程師面試題:5000 筆列表卡頓,你會怎麼優化?

2026年6月6日

前端工程師面試題:MobX、Redux、Zustand 怎麼選?

2026年6月5日

最新文章
全部 →
前端 CI/CD 與正式環境除錯:從 Pull Request 到事故排查
2026-06-24
即時資料怎麼選?Polling、SSE、WebSocket 比較
2026-06-23
前端系統設計:如何拆元件、資料流與大型專案架構?
2026-06-22
無障礙不是加 ARIA:語意化 HTML、鍵盤操作與焦點管理
2026-06-21
CSS 與 RWD 面試整理:Flexbox、Grid、定位與層疊脈絡
2026-06-19
← 返回文章列表

前端工程師面試題:useMemo 和 useCallback 差在哪?什麼時候不該用?

2026年6月4日·約 4 分鐘閱讀·
前端面試系列React效能優化

useMemo 和 useCallback 是 React 面試高頻題。

這題不是在問你會不會背 API,而是在看你是否理解:

  • React component re-render 時會重新執行 function body
  • JavaScript 裡物件和函式會產生新的 reference
  • memoization 有成本,不是加越多越好
  • useMemo、useCallback、React.memo 要一起理解

useMemo 是什麼?

useMemo 用來記住「計算結果」。

const filteredProducts = useMemo(() => {
  return products.filter((product) => product.category === selectedCategory);
}, [products, selectedCategory]);

當 dependency 沒變時,React 會重用上一次的結果,不重新執行這段計算。

適合情境:

  • 過濾大量資料
  • 排序大量資料
  • expensive calculation
  • 產生傳給 child 的穩定 object / array

面試回答:

useMemo 是 memoize 計算結果。當 dependencies 沒變時,React 會重用上一次的 value,避免昂貴計算重複執行,或避免每次 render 都產生新的 object / array reference。


useCallback 是什麼?

useCallback 用來記住「函式 reference」。

const handleSelect = useCallback((id: string) => {
  setSelectedId(id);
}, []);

它可以理解成:

const handleSelect = useMemo(() => {
  return (id: string) => {
    setSelectedId(id);
  };
}, []);

適合情境:

  • callback 傳給 React.memo 包住的 child
  • callback 是 useEffect dependency
  • 第三方 library 需要穩定 function reference

useMemo / useCallback 差異

一句話:

useMemo 記住值,useCallback 記住函式。

Hook記住什麼常見用途
useMemo計算後的 value過濾、排序、衍生資料、穩定 object
useCallbackfunction reference傳給 memo child、effect dependency

React.memo 又是什麼?

React.memo 是 memoize component render result。

const ProductRow = memo(function ProductRow({ product, onSelect }) {
  return <button onClick={() => onSelect(product.id)}>{product.name}</button>;
});

如果 props 沒變,React 可以跳過這個 child 的 render。

但如果每次 parent render 都傳新的 function:

<ProductRow product={product} onSelect={(id) => setSelectedId(id)} />

onSelect reference 每次都變,React.memo 就可能失去效果。

這時才可能需要 useCallback:

const handleSelect = useCallback((id: string) => {
  setSelectedId(id);
}, []);
 
<ProductRow product={product} onSelect={handleSelect} />

什麼時候不該用?

不要看到函式就加 useCallback,也不要看到計算就加 useMemo。

不太需要 memo 的例子:

const fullName = useMemo(() => {
  return `${firstName} ${lastName}`;
}, [firstName, lastName]);

這種計算太便宜,memo 的 dependency 比對和心智成本可能比計算本身還高。

不需要 useCallback 的例子:

function Button() {
  const handleClick = () => {
    console.log("click");
  };
 
  return <button onClick={handleClick}>Click</button>;
}

如果沒有傳給 memo child,也沒有作為 effect dependency,通常不用特別包。


常見追問

useMemo 可以避免 component re-render 嗎?

不能。

useMemo 只能避免某段計算重跑,不能阻止 component 本身重新執行。

如果要避免 child 不必要 re-render,通常要搭配 React.memo 和穩定 props。

dependency array 寫錯會怎樣?

可能拿到舊資料,也可能造成 memo 失效。

如果漏 dependency,useMemo / useCallback 可能一直使用舊 closure。

useCallback 會讓函式不被建立嗎?

更準確地說,它讓 React 在 dependencies 沒變時回傳同一個 function reference。不要把它理解成完全沒有成本。


面試回答模板

useMemo 是記住計算結果,useCallback 是記住函式 reference。它們主要用在昂貴計算、穩定傳給 memo child 的 props,或避免 effect dependency 一直變。它們不是保證效能變好的魔法,因為 memoization 本身也有成本。我通常會先用 React DevTools Profiler 確認瓶頸,再針對昂貴計算或不必要 re-render 加 useMemo、useCallback 或 React.memo。

分享:XLinkedIn
← 上一篇前端工程師面試題:React Router v5 升級 v6 改了哪些?
下一篇 →前端工程師面試題:MobX、Redux、Zustand 怎麼選?