iT邦幫忙

2021 iThome 鐵人賽

DAY 24
0
自我挑戰組

Re: 新手讓網頁 act 起來系列 第 24

Re: 新手讓網頁 act 起來: Day24 - React Hooks 之 useMemo

  • 分享至 

  • xImage
  •  

前言

昨天我們介紹過如何使用 React.memo 與 useCallback 來做效能優化,而 useMemo 這個 hook 一樣也是用來優化效能的,今天就來介紹 useMemo 的基本使用方式吧!

useMemo

首先,剛接觸 React 時,看到 memo 與 useMemo 有時一定會搞混。memo 是一個 HOC (Hight order component) ,接收一個元件並且回傳一個元件。而 useMemo 是 React hooks 的其中一個 hook ,與 useCallback 類似,接收兩個參數

  1. callback 並且回傳一個值
  2. dependency array
const memorizeValue = useMemo(() => computeExpensiveValue(a, b), [a, b])

useMemo 會將第一個傳進去的 callback return 的 value 記住,然後當 dependecny 有變動時,才會重新呼叫 callback 並 return 新的值。

看到這邊可以發現,它跟 useCallback 實在太像了!useCallback 是會紀錄函式,而 useMemo 是紀錄值。所以,以下的等式是成立的!

useCallback(fn, []) = useMemo(() => fn, [])

雖然 useMemo 能夠取代 useCallback ,但透過不同名稱的 api 能夠聚焦在不同的情境上。

接下來就來看看如何使用 useMemo 吧!

function computeExpensiveValue(number) {
  console.log('execute expensive function')
  return number <= 0 ? 1 : number * computeExpensiveValue(number - 1);
}

function App() {
  const [number, setNumber] = React.useState(10)
  const [click, setClick] = React.useState(0)
  const result = computeExpensiveValue(number)

  function onChangeHandler(e) {
    setNumber(Number(e.target.value))
  }

  return (
    <div>
      <input type="text" onChange={onChangeHandler} value={number} />
      {result}
      <button onClick={() => setClick(click + 1)}>{click}</button>
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById('root'))

上面範例中,我們定義了遞迴函式,當我們給的數字越大,執行的次數會隨之增加。當我們按下 button 改變 click 的 state 觸法元件 re-render 這個函式都會重新執行。

但其實我們希望這個遞迴函式,只要在數字改變的時候再做計算,其他的 state 改變都應改與它無關,所以這個時候就可以使用 useMemo 解決這個問題。

const result = React.useMemo(() => fibonacci(number), [number])

當我們使用 useMemo 紀錄這個 result ,只要 number 的 state 不改變,就算元件 re-render ,也都不會重新執行遞迴函式。

以上就是關於 useMemo 的基本介紹與使用方式,如果有任何問題都歡迎在下方留言!

該文章同步發佈於:我的部落格


上一篇
Re: 新手讓網頁 act 起來: Day23 - useCallback 與 React.memo
下一篇
Re: 新手讓網頁 act 起來: Day25 - useMemo 和 useCallback
系列文
Re: 新手讓網頁 act 起來30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
justlikett
iT邦新手 5 級 ‧ 2021-11-17 17:57:41

https://ithelp.ithome.com.tw/upload/images/20211117/20135690qS9Qz1NS0D.jpg
因為我都會跟著你的內容,先打一遍,再來慢慢理解,現在卡關了,無法產生跟你一樣的內容!!
不好意思!可否提供 fibonacci 這個函數內容,謝謝!!

Will iT邦新手 4 級 ‧ 2021-11-18 17:14:47 檢舉

Sorry 那個地方是我打錯,感謝指正!
這邊是一個遞迴函式,fibonacci 這個名稱更改成 computeExpensiveValue 就行了

我要留言

立即登入留言