useMemo
5. useMemo
📌 範例程式碼
import { useMemo } from "react";
const result = useMemo(() => {
return expensiveFunction(data);
}, [data]);
📌 程式碼結構
const result = useMemo(() => 計算邏輯, [依賴項陣列]);
- 使用上跟
useEffect類似,但在最後會有回傳值- 後方陣列為空,代表頁面初次載入時才會執行
📌 用途
- 避免「重複計算」
- 在一個元件中可能會使用到多個
useState,只要其中一個觸發就會將整個元件 re-render,這時如果變數使用的是useMemo那麼useState所觸發的 re-render 不會去影響useMemo的變數 - 常被使用在 搜尋 和 排序
📌 重點
👉 只有依賴的資料改變時才重新計算
warning
在 react 中有一個方法叫做memo,memo和useMemo兩個沒有關聯性,一個是 方法,一個是 hook,只是實務上常會搭配useMemo和usecallback來使用
import { memo } from "react";
詳細說明
import { useMemo, useState } from "react";
const ProductList = ({ products }) => {
const [filterText, setFilterText] = useState("");
const [count, setCount] = useState(0); // 用來測試「不相關的觸發」
// 1. 觸發條件:[products, filterText] 只要其中一個變了,就會觸發
// 2. 被觸發後會做什麼:重新執行箭頭函式裡的 Array filter 邏輯
// 3. 預設是什麼樣:初次渲染時會執行一次,並把結果記下來
// 4. 如果沒有被觸發:當 count 改變時,React 直接回傳舊的緩存值,完全不跑 filter
const filteredProducts = useMemo(() => {
console.log("--- 正在執行昂貴的過濾運算 ---");
return products.filter((p) => p.name.includes(filterText));
}, [products, filterText]);
return (
<div>
<input
value={filterText}
onChange={(e) => setFilterText(e.target.value)}
placeholder="搜尋商品..."
/>
<button onClick={() => setCount(count + 1)}>
點擊次數:{count} (這不會觸發過濾運算)
</button>
<ul>
{filteredProducts.map((p) => (
<li key={p.id}>{p.name}</li>
))}
</ul>
</div>
);
};
📌 useMemo vs useCallback
| Hook | 用途 |
|---|---|
| useMemo | 記住「計算結果」 |
| useCallback | 記住「函式」 |