iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
Modern Web

react 學習記錄系列 第 19

[Day19]我的 react 學習記錄 - memo

  • 分享至 

  • xImage
  •  

這篇文章的主要內容

簡單介紹優化 react 的其中一個方法 - memo


memo

前面有提到當狀態改變時 react 會 re-render 整個元件,所以元件內的子元件也會一起被 re-render。

import { useState } from "react";

type Props = { number: number };

function One({ number }: Props) {
  console.log("One render"); // 觀察元件是否 re-render
  return <p>One number: {number}</p>;
}
function Two({ number }: Props) {
  console.log("Two render"); // 觀察元件是否 re-render
  return <p>Two number: {number}</p>;
}

function App() {
  const [number, setNumber] = useState(0);
  const [count, setCount] = useState(0);

  function handleNumber() {
    setNumber(number + 1);
  }
  function handleCount() {
    setCount(count + 1);
  }
  console.log("--------App render--------");
  return (
    <div>
      <One number={number} />
      <Two number={count} />
      <button onClick={handleNumber}>add number</button>
      <button onClick={handleCount}>add count</button>
    </div>
  );
}

<One /><Two /> 兩個元件都接收一個 number 的 props 並把它顯示在畫面上。

因為它們都在 <App /> 裡面,所以當 App 的 state 改變 re-render 時兩個元件也都會一起 re-render。

memo1

可以看到不管點擊 number 還是 count 都會 re-render 元件。

如果 number 的 state 會不斷地改變,但是 count 並不會一直改變,那 count 的 re-render 就會顯得有點多餘。

這個時候就可以使用到 memo。


Syntax

const MemoizedComponent = memo(SomeComponent, arePropsEqual?)

SomeComponent: 一個希望 react 幫你記住的元件。
arePropsEqual?: compare function,通常不會主動使用這個參數,這個 function 可以接到兩個參數,舊的 props 跟新的 props 預設情況 react 會透過 Object.is() 一個一個的進行,當其中有個不同的時候就會 re-render 元件,如果所有的比較都是 true,就不會 re-render。

MemoizedComponent: memo 會回傳一個被記下來的元件,使用方式跟其他的 react 元件一樣。

注意事項

  • memo 並不是 react hook,請不要在元件內部使用,在元件外使用,當作在建立一個全新的 react 元件。
  • 如果 memoized 的元件是放在 react context 的裡面的話,當 context 改變觸發 re-render,時即使 props 沒有改變還是會觸發 re-render,memo 只有作用在 props 的部分。
  • 並不是所有元件都需要被 memo,因為 memo 也是有計算成本,大多數的網站並不會需要 memo,如果網站使用時起來沒有特別慢或是卡頓,就不需要使用。
  • 比起使用 memo,應該要好好的管理網站渲染的邏輯以及避免使用非必要的 global state,盡量把 state 的範圍縮小,避免全域狀態改變時觸發不必要的 re-render。

馬上就把兩個元件放到 memo 試試看吧。

const One = memo(function One({ number }: Props) {
  console.log("One render"); // 觀察元件是否 re-render
  return <p>One number: {number}</p>;
});

const Two = memo(function Two({ number }: Props) {
  console.log("Two render"); // 觀察元件是否 re-render
  return <p>Two number: {number}</p>;
});

memo 使用起來就是這麼的簡單直覺。

memo2

這樣就變成了只有當傳下去的變數有改變時才會觸發那個元件的 re-render。


memo - react document

如果內容有誤再麻煩大家指教,我會盡快修改。
下一篇簡單介紹優化 react 的另一個方法 - useMemo

這個系列的文章會同步更新在我個人的 Medium,歡迎大家來看看 👋👋👋
Medium


上一篇
[Day18]我的 react 學習記錄 - Render Props
下一篇
[Day20]我的 react 學習記錄 - useMemo
系列文
react 學習記錄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言