iT邦幫忙

2022 iThome 鐵人賽

DAY 20
3
Software Development

React框架白話文運動系列 第 20

React白話文運動20-React Hook-useCallback

  • 分享至 

  • xImage
  •  

前言

嗨,我是Hogan
目前在經營自己的自媒體 hogan.tech
主要分享一些有關於程式碼、軟體和科技業經驗分享
有興趣的讀者可以進一步關注我,進而獲得更多資訊唷!

未來文章一併更新於此網站 Hogan.B Lab
並且包含多語系 繁體中文英文日文簡體中文
觀看分類:React 白話文運動其他系列

如果想要快速查找其他文章請點選目錄

成立 hogan.tech 的初衷是
希望每個正在這條路上探索的人,
都可以透過 Hogan.tech 嘗試進入程式領域。


前一篇會介紹新的 hook - useMemo

  1. 複習 useEffect 的相依陣列
  2. useMome用法

這一篇則是介紹與useMemo 相似的hook - useCallback

  1. 複習 useMemo
  2. useCallback 寫法
  3. useCallback 與 useMemo 差異

複習 useMemo

這邊複習一下 useMemo 的語法,useMemo 會呼叫傳遞給他的引數函式,並暫存著結果

如果使用前一篇的 useEffect 的做法,會重新的再去執行 expensiveCalculation

缺點的話,很明顯的如果函式需要執行的時間很長

那麼就需要一直重複的執行,相當影響效能

import { useEffect } from "react";
import { useMemo } from "react";
import { useState } from "react";

export default function Increment() {
    const [count, setCount] = useState(0);
    const calculation = useMemo(() => expensiveCalculation(count), [count]);

    const increment = () => {
        setCount((c) => c + 1);
    };

    return (
        <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;
};


useCallback 寫法

這邊用一個簡單的情境來舉例:

const fn = () => {
	console.log("hello");
	console.log("world");
};

useEffect(()=>{
	console.log("fresh render");
	fn();
},[fn]);

在以上的程式碼中,fn 會印出「hello」以及「world」,useEffect 又將 fn 放入相依陣列裡面

不過前一篇有提過,如果在相依陣列中,放入函式、陣列、物件會是不同的實體(instance)

所以JavaScript 會視為是不相同的,會去重新觸發 Effect 裡面的函式,印出「fresh edner」訊息

如果要解決此問題,我們可以使用 useCallback 包裹著我們要的韓式,並且傳入

const fn = useCallback(() => {
	console.log("hello");
	console.log("world");
},[]);

useEffect(()=>{
	console.log("fresh render");
	fn();
},[fn]);

其中 useCallback 也有兩個引數,分別為函式引數以及相依陣列

以上述的例子來說,他會接收一個相依陣列作為一個引數值

不過因為我放入的是空陣列,所以 fn 本身是不會改變的

這樣可以避免因「函式、陣列、物件會是不同的實體(instance)」而重新觸發 Effect 裡面的函式


useCallback 與 useMemo 差異

useCallback 與 useMemo 真的非常相似卻又有些不同

useCallback 本質上回傳 callback function ,因此在下面的例子中

const fn = useCallback(() => {
	console.log("hello");
	console.log("world");
},[]);

callback function 是指

() => {
	console.log("hello");
	console.log("world");
}

useMemo 本質上是回傳一個值,因此在下面的例子中

useMemo(() => expensiveCalculation(count), [count]);


const expensiveCalculation = (num) => {
    console.log("Calculating...");
    for (let i = 0; i < 1000000000; i++) {
        num += 1;
    }
    return num;
};

回傳的值為 expensiveCalculation 的回傳值 num


結語

這一篇講解了與 useMemo 很相似的 useCallback

React Hook 系列,還有幾個尚未介紹

講解完之後就會進入到 Flux & Redux 講解

如果有任何建議與疑問也歡迎留言!

如果喜歡此系列文章,請不吝於按下喜歡及分享,讓更多人看到唷~


上一篇
React白話文運動19-React Hook-useMemo
下一篇
React白話文運動21-React Hook-useLayoutEffect
系列文
React框架白話文運動30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言