iT邦幫忙

2022 iThome 鐵人賽

DAY 26
0

昨天我們介紹了什麼是 memorized hook,介紹他們是如何提升 React 的效能。接著,我們來更詳細一點的介紹各個 hook 要怎麼使用。

useMemo 介紹

useMemo 是個可以避免不必要重複執行的 memorized hook。他會偵測傳入 hook 中的依賴參數,如果依賴參數沒有發生變化,則不會更新回傳值。基於這一點,他可以拿來做許多提升效能的工具。

語法

這邊稍微再說明一下語法:

const returnValue = useMemo(()=> someHeavyFn(a, b), [a, b])

第一個參數要放入一個 callback function,其中放入要執行的複雜 function;第二個則要放入依賴參數,也就是要偵測有無變化的變數,需要放入一個 Array,跟過去介紹的 useEffect 相同,若 Array 中沒有放入任何值,則回傳值不會改變。
函數的回傳值是我們要執行的 function 執行後的值,可以直接用做元件內的資料或傳值。

特性

useMemo 會在元件渲染時執行,要特別注意不要用 useMemo 做不會在渲染中執行的事,例如 side effect ,應交由渲染後執行的 useEffect 去做。

應用 1:避免重複執行複雜程式

當元件被重新渲染時,有些 function 我們不需要重新執行,這些 function 可能耗時極長,有可能很吃效能,若每一次都執行將會大大拖累整個網站。
因此,這種 function 就可以使用 useMemo:

let a = 1, b = 2;
const heavyFunction = (a, b) => {
    for(let i = 0; i < 1000000; i++){};
    return a + b
}

const number = useMemo(() => heavyFunction(a, b), [a, b])

應用二:避免被父元件強制渲染

當父元件更新時,有時候子元件不見得也需要強制更新。這時候也可以使用 useMemo。
這個狀況下,一旦父元件被按鈕更新狀態,便會強制子元件也更新:

const Child = () => {
    let counter = useRef(0);
    const myFunction = () => {
      counter.current++;
    };
  const value = myFunction();
    return (
        <div>
            更新次數:{counter.current}
        </div>
    )
}

const Parent = () => {
    const [pressCounter, setPressCounter] = useState(0);
    return (
        <div>
            <Child />
            <button onClick={()=> setPressCounter(pressCounter + 1)}>更新</button>
        </div>
    )
}

若是將 value = myFunction() 的部分加上 useMemo 來阻止重新執行的話,就可以避免元件也被重新渲染:

// 不使用依賴變數,保持不變
const value = useMemo(()=>myFunction(), [])

參考資料
useMemo - React
React 性能優化那件大事,使用 memo、useCallback、useMemo
React Hooks: 深入剖析 useMemo 和 useEffect

以上是比較常見的用法,主要就是避免 function 做不必要的執行。他的用法跟 useCallback 相似,但又有所不同,明天會再介紹 useCallback。


上一篇
[Day25]用 React 讓網站動起來:認識 memorize hook
下一篇
[Day27]用 React 讓網站動起來:useCallback
系列文
用React讓網頁動起來: React基礎與實作30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言