banner
我是老王

我是老王

我用尽全力,过着平凡的生活!
github
twitter
email
follow
discord user

React性能優化 | 別再讓你的 React 頁面卡成PPT了!useMemo必學

做過 React 項目的應該都遇到過這種情況:開發時頁面絲般順滑,但一上線數據量大了就卡得要死。點個按鈕要等三秒,比我家貓起床都慢。

別急著甩鍋給後端,今天說個 React 裡經常被忽視但很有用的東西 —— useMemo

這玩意兒名字聽起來像 "有記憶",其實就是組件的省電模式。

useMemo 是什麼#

想像你有個同事,每次問他複雜問題都要算半天。關鍵是每問一次他就重算一遍,哪怕數據壓根沒變。

useMemo就像給這個同事裝了個記憶:上次算過的結果記著呢,你要不要直接用?

本質就是緩存計算結果,只要依賴沒變就直接返回舊結果,不重複計算。

語法長這樣:

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

只有當ab改了才重新算,否則直接返回上次的結果。

什麼時候用#

1. 計算很重的時候#

比如處理5000條訂單數據做排序、過濾、統計。這種操作每次都跑風扇都要起飛,而組件一天要渲染幾十次。

const processedData = useMemo(() => {
  return heavyProcess(orders); // 耗時操作
}, [orders]); // 只有orders變了才重算

這樣就從每次渲染都算變成只算一次。

2. 給子組件傳對象或數組#

子組件用了React.memo但還是一直重渲染?很可能是因為傳過去的 prop 每次都是新的引用。

比如這樣:

// 每次渲染都創建新數組,哪怕內容一樣
<MyComponent filters={[{ type: "active" }]} />

解決方法:

const stableFilters = useMemo(() => [{ type: "active" }], []);
<MyComponent filters={stableFilters} />;

這樣對象地址就不變了,React.memo才能正常工作。

3. 作為其他 Hook 的依賴項#

const config = { userId, theme };

useEffect(() => {
  fetchUserData(config);
}, [config]); // 問題來了!

每次渲染config都是新對象,useEffect就會重複觸發。

解決:

const config = useMemo(() => ({ userId, theme }), [userId, theme]);

useEffect(() => {
  fetchUserData(config);
}, [config]);

現在只有userIdtheme變了config才更新。

useMemo vs useCallback#

這兩個容易搞混:

Hook緩存的是啥?使用場景
useMemo一個值複雜計算、對象 / 數組、作為依賴
useCallback一個函數本身防止函數變化導致子組件重渲染
// useMemo:緩存"計算結果"
const total = useMemo(() => items.reduce(sum), [items]);

// useCallback:緩存"函數本身"
const handleClick = useCallback(() => doSomething(id), [id]);

常見坑點#

依賴項寫錯#

useMemo(() => expensive(), [{}]); // 每次都是新對象!
useMemo(() => expensive(), [[]]); // 每次都是新數組!

確保依賴項是穩定的值。

濫用 useMemo#

不是所有計算都要緩存。如果只是簡單的a + b,用useMemo反而浪費。

React 官方說過:過早優化是萬惡之源。先找到性能瓶頸再用useMemo

總結#

什麼時候用:

  • 計算很重
  • 傳給memo子組件的對象 / 數組
  • 作為其他Hook的依賴項

記住:它是瑞士軍刀,不是創可貼。

頁面卡了別急著換框架,先看看是不是該給 useMemo 發工資了。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。