首頁 >web前端 >js教程 >透過記憶化提高 React 應用程式的效能:探​​索 useMemo、useCallback 和 React.memo

透過記憶化提高 React 應用程式的效能:探​​索 useMemo、useCallback 和 React.memo

Linda Hamilton
Linda Hamilton原創
2024-11-05 22:34:021010瀏覽

Boost Your React App

提高網站效能是增強使用者體驗和確保可靠、響應靈敏的介面的關鍵一步。如果您正在開發包含一些資源密集型元件的 React 或 Next.js 項目,那麼很自然會擔心它們對效能的影響。這就是 React 中的記憶化的用武之地——它有助於加快這些「昂貴」組件的速度,從而為用戶帶來更流暢的體驗。

在本文中,我將介紹記憶化並介紹可以最佳化應用程式效能的 React hooks,例如 useMemo()、useCallback() 和 React.memo 高階元件 (HOC)。讓我們開始吧!

React 中的記憶化是什麼?

記憶化是一種透過快取計算任務(例如函數呼叫)的結果來加速程式的技術,這樣,如果再次提供相同的輸入,則傳回快取的結果而不是重新計算它。

useMemo Hook:在 React 中快取結果

useMemo 是一個鉤子,可以在重新渲染或更新元件之間快取或記憶函數的結果。

因此,透過使用此鉤子,您可以快取元件中函數的結果,並且在下次重新渲染時,如果函數的輸入未更改,您的元件將使用快取結果。

如何實作 useMemo:

useMemo 是一個掛鉤,它將未最佳化的函數作為回調和依賴項列表。然後 React 決定何時在初始渲染期間或後續重新渲染時呼叫此函數。

  • 初始渲染:在初始渲染期間,React 會呼叫 useMemo 函數來計算並儲存您提供的回調函數的結果。

  • 重新渲染:重新渲染時,React 呼叫 useMemo 來檢查依賴項是否已更改。如果依賴項沒有更改,React 會重複使用上次渲染期間儲存的快取值。但是,如果依賴項發生變化,useMemo 會再次呼叫回調函數來重新計算更新後的值並將其儲存在快取中。

範例:

import React, { useMemo } from 'react';

const MyComponent = ({ number }) => {
  const squaredNumber = useMemo(() => number * number, [number]);

  return <div>Squared Number: {squaredNumber}</div>;
};

squaredNumber 僅當數字改變時才計算。 useMemo 會快取此計算,因此不會在每次渲染時進行不必要的重新計算。

useCallback Hook:快取函數定義

useCallback 是一個鉤子,用於快取或記憶元件重新渲染或更新之間的函數定義。

透過使用這個鉤子,你可以在重新渲染時儲存函數的定義,因此只要函數的依賴項沒有改變,React就會重複使用這個快取的版本。

如何實作useCallback:

useCallback 是一個掛鉤,它接受一個函數(作為回調)和一個依賴項列表。然後,React 決定何時返回(而不是調用)此函數 - 無論是在初始渲染期間還是在後續重新渲染期間。

  • 初始渲染:在初始渲染期間,React 呼叫 useCallback 來儲存您作為回調傳遞的函數。

  • 重新渲染:重新渲染時,React 呼叫 useCallback 來檢查依賴項是否已更改。如果依賴項沒有更改,React 會重複使用上次渲染期間儲存的快取函數。如果依賴項發生更改,useCallback 將儲存並傳回更新後的函數。

範例:

import React, { useMemo } from 'react';

const MyComponent = ({ number }) => {
  const squaredNumber = useMemo(() => number * number, [number]);

  return <div>Squared Number: {squaredNumber}</div>;
};

React.memo 函數:防止不必要的重新渲染

如你所知,當你有父元件和子元件時,對父元件的 state 或 props 的任何更新都會導致其所有子元件重新渲染。在小型專案中,這可能不是問題,但在更大、更複雜的應用程式中,子元件不必要的重新渲染可能會影響效能。為了解決這個問題,React 提供了 memo() 函數。

memo(或 React.memo)函數可讓您包裝元件以防止其在父級更新時重新渲染。包裝的元件只有在其自身的 props 或 state 改變時才會重新渲染。

當你第一次在元件上呼叫 memo() 時,React 會渲染並快取該元件。在後續渲染中,只要元件的 props 和狀態沒有改變,React 就會使用這個快取的版本。請記住,memo() 僅避免重新渲染未更改的 props 和狀態 - 一旦它們發生更改,memo() 就會相應地重新渲染並更新快取的元件。

如何實作 React.memo:

要在元件中實作 memo,只需使用 memo() 或 React.memo() 包裝您想要防止不必要的重新渲染的元件:

import React, { useState, useCallback } from 'react';

const MyComponent = () => {
  const [count, setCount] = useState(0);
  const [multiplier, setMultiplier] = useState(2);

  // Memoize the callback with `count` as a dependency
  const calculate = useCallback(() => {
    console.log("Calculating:", count * multiplier);
  }, [count]);

  return (
    <div>
      <p>Count: {count}</p>
      <p>Multiplier: {multiplier}</p>
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <button onClick={() => setMultiplier(multiplier + 1)}>Increment Multiplier</button>
      <button onClick={calculate}>Calculate</button>
    </div>
  );
};

export default MyComponent;

注意:
如果將物件作為 prop 傳遞給包裝在 memo() 中的元件,則即使該物件沒有更改,該元件仍將在每次更新時重新渲染。發生這種情況是因為 React 使用 Object.is 來比較先前和目前的 props。雖然 Object.is(3, 3) 傳回 true,但 Object.is({}, {}) 傳回 false,因為兩個不同的物件參考永遠不會被視為相等。

為了避免這種情況,您可以使用 useMemo 來快取物件並在渲染之間保持相同的參考:

import React from 'react';

const MyComponent = ({ data }) => {
  return <div>{data.value}</div>;
};

export default React.memo(MyComponent);

在此範例中,useMemo 確保資料物件具有相同的引用,從而防止 MyComponent 不必要的重新渲染。

謝謝您閱讀我的文章!如果您想了解有關 Next.js、React、JavaScript 等的更多信息,請隨時關注我的網站:saeed-niyabati.ir。如有任何問題,請隨時與我們聯絡。下次見!

以上是透過記憶化提高 React 應用程式的效能:探​​索 useMemo、useCallback 和 React.memo的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn