iT邦幫忙

2024 iThome 鐵人賽

DAY 23
0
Modern Web

現在就學React.js 系列 第 23

用useMemo優化效能 - Day23

  • 分享至 

  • xImage
  •  

useMemo 是 React 中用來記憶化計算結果的一個 Hook。能夠在每次重新渲染的時候緩存計算的結果,只有當某些依賴項發生變化時才會重新計算,這在處理昂貴的計算上帶來更好的性能優化。

useMemo基本語法:


const cachedValue = useMemo(calculateValue, dependencies)

//範例
const cachedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

  • 第一個參數:一個計算函數,通常包含一個比較「昂貴」的運算邏輯。
  • 第二個參數:一個依賴項的陣列,當這些依賴項發生變化時,React 會重新執行計算函數。

當依賴項沒有發生變化時,useMemo 將返回上一次的計算結果,從而避免重新計算。


實際範例:Todo 列表與計數器

以下是一個應用範例,展示了如何使用 useMemo 來優化性能。在這個範例中,我們有一個 Todo 列表與一個計數器,並進行了一個昂貴的計算。透過 useMemo,我們將只在必要時重新計算,而不會每次渲染都執行計算邏輯。

程式碼範例:


import { useState, useMemo } from 'react';

const App = () => {
  // 定義兩個狀態:count 和 todos
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);

  // 使用 useMemo 記憶化昂貴的計算,當 count 改變時才會重新計算
  const calculation = useMemo(() => expensiveCalculation(count), [count]);

  // 增加 count 的函數
  const increment = () => {
    setCount(c => c + 1);
  };

  // 新增 todo 項目的函數
  const addTodo = () => {
    setTodos(t => [...t, 'New Todo']);
  };

  return (
    <div>
      <div>
        <h2>My Todos</h2>
        {todos.map((todo, index) => (
          <p key={index}>{todo}</p>
        ))}
        <button onClick={addTodo}>Add Todo</button>
      </div>
      <hr />
      <div>
        Count: {count}
        <button onClick={increment}>+</button>
        <h2>Expensive Calculation</h2>
        {calculation}
      </div>
    </div>
  );
};

// 模擬一個耗時計算的函數
const expensiveCalculation = num => {
  console.log('Calculating...');
  for (let i = 0; i < 1000000000; i++) {
    num += 1;
  }
  return num;
};

export default App;


範例說明:

  1. 使用 useState 狀態管理
    • useState 來管理兩個狀態:
      • count:用來儲存計數器的值。
      • todos:用來存放 Todo 列表的內容。
  2. useMemo 的應用
    • useMemo 用來緩存「昂貴的計算結果」,當依賴的 count 狀態改變時,才會重新計算。如果 count 沒有變化,React 會直接使用先前緩存的結果,避免不必要的重複計算。
  3. Todo 列表與計數器功能
    • 使用者按下「Add Todo」按鈕來新增一個新項目到 Todo 列表。
    • 使用者按下「+」按鈕來增加計數,當計數器變化時,會觸發昂貴的計算。

https://ithelp.ithome.com.tw/upload/images/20241007/20159895X02LGLQHSv.png
只有按下「+」按鈕,才會觸發重新計算

使用 useMemo 的好處

  1. 性能優化:在這範例中,expensiveCalculation 是一個模擬的耗時計算。如果我們沒有使用 useMemo,每次 todos 改變時,React 都會重新執行這個計算,造成不必要的資源浪費。通過 useMemo,我們只會在 count 變化時重新執行計算,從而提升性能。
  2. 避免不必要的重新渲染:雖然 todos 變化不會影響 count 的計算,但如果沒有使用 useMemo,每次重新渲染都會重新計算 expensiveCalculationuseMemo 能夠有效地防止這種不必要的重新計算。

useMemo 的使用注意事項

  • 適用於昂貴的計算useMemo 的主要用途是優化昂貴的計算過程。如果你的計算或渲染過程非常簡單,那麼使用 useMemo 可能反而增加了不必要的複雜度。
  • 依賴項的正確性:在設置 useMemo 的依賴項時,要確保列出所有在計算過程中使用到的狀態或 props。如果漏掉了某些依賴項,可能會導致計算結果不更新,造成應用邏輯錯誤。

總結

useMemo 可以幫助你在 React 應用中記憶化計算結果,從而提升性能。尤其是在處理昂貴的計算或需要避免不必要的重複渲染時,useMemo 能夠有效地避免重複的計算。

參考資料

後記

本文將會同步更新到我的部落格

黃禎平 – Medium


上一篇
useContext 輕鬆共享資料之props drilling的解方 - Day22
下一篇
提升組件的效能-memo - Day24
系列文
現在就學React.js 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言