ReactJS - 使用 useCallback:初學者指南

您好,未來的 React 開發者!今天,我們將深入探討 React 的強大 Hooks 之一:useCallback。別擔心你對編程還是新手;我會逐步引導你了解這個概念,就像我過去幾年來對許多學生所做的一樣。讓我們一起踏上這個令人興奮的旅程吧!

ReactJS - Using useCallback

useCallback 是什麼?

在我們深入了解之前,讓我們先了解 useCallback 的相關知識。想像一下你正在烤餅乾(我喜歡這個比喻,因為,好吧,誰會不喜歡餅乾呢?)你有一個每次都會使用的特別配方。useCallback 就像寫下那個配方一次,並在每次需要烤餅乾時使用它,而不是每次都試圖記住它。

在 React 的術語中,useCallback 是一個 Hook,它通過記憶(memoization)函數來幫助我們優化應用程序的性能。

useCallback Hook 的語法

讓我們看看如何寫 useCallback

const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);

別慌張!我知道這可能看起來很複雜,但我們會一一解析:

  1. memoizedCallback:這是 useCallback 返回的函數。
  2. () => { doSomething(a, b); }:這是我們想要記憶的函數。
  3. [a, b]:這被稱為依賴數組。它告訴 React 什麼時候重新創建我們的函數。

把它想成這樣:你正在告訴 React,“嘿,記住這個函數對我來說,而且只有當 ab 變化時才給我一個新的。”

使用 useCallback

現在,讓我們透過一個簡單的例子來看看 useCallback 的實際應用:

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

function Counter() {
const [count, setCount] = useState(0);

const increment = useCallback(() => {
setCount(c => c + 1);
}, []);

return (
<div>
Count: {count}
<button onClick={increment}>Increment</button>
</div>
);
}

讓我們來解析這個例子:

  1. 我們從 React 中導入 useCallback
  2. 我們使用 useState 創建一個狀態變量 count
  3. 我們使用 useCallback 定義一個 increment 函數。這個函數會將我們的計數增加 1。
  4. 空數組 [] 作為第二個參數意味著這個函數從不會變化。
  5. 我們渲染我們的計數和一個按鈕,當點擊時會調用 increment

useCallback 的使用場景

現在你可能在想,“我應該什麼時候使用 useCallback?”這個問題問得好!讓我們看看一些常見的情況:

1. 將 Callbacks 傳遞給經過優化的子組件

想像一下你有一個被 React.memo 包裹的子組件(現在不必擔心這個,我們會在將來的課程中介紹)。你想要將一個函數傳遞給這個組件:

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

function ParentComponent() {
const [count, setCount] = useState(0);

const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);

return (
<div>
<ChildComponent onClick={handleClick} />
<p>Count: {count}</p>
</div>
);
}

const ChildComponent = React.memo(({ onClick }) => {
console.log("Child rendered!");
return <button onClick={onClick}>Increment</button>;
});

在這裡,useCallback 確保當 count 變化時,handleClick 只會變化,從而防止 ChildComponent 不必要地重新渲染。

2. 在 useEffect 的依賴中

useCallback 在函數是 useEffect Hook 的依賴時也很有用:

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

function DataFetcher() {
const [data, setData] = useState(null);

const fetchData = useCallback(() => {
// 想像這裡是從 API 獲取數據
setTimeout(() => setData("New Data!"), 1000);
}, []);

useEffect(() => {
fetchData();
}, [fetchData]);

return <div>{data ? data : "Loading..."}</div>;
}

在這個例子中,useCallback 確保 fetchData 在每次渲染時都不會變化,從而避免不必要的副作用運行。

優點和缺點

讓我們總結一下 useCallback 的優點和缺點:

優點 缺點
防止不必要的重新渲染 讓代碼變得更複雜
為子組件優化性能 過度使用可能導致性能問題
useEffect 的依賴中很有用 需要理解閉包和記憶
有助於創造穩定的 callbacks 在簡單組件中可能不會提供顯著的好處

結論

哇!我們今天涵蓋了很多內容。useCallback 是你 React 工具包中的一個強大工具,但就像任何工具一樣,使用它時要明智。隨著你繼續你的 React 之旅,你將會培養出使用 useCallback 的直覺。

記住,優化是很好的,但清晰、易讀的代碼更重要。不要覺得有壓力去到處使用 useCallback —— 在它對你的應用程序有意義時使用它。

持續練習,保持好奇心,並且快樂編程!並且記住,就像完善一個餅乾配方一樣,精通 React 需要時間和耐心。你可以做到的!

Credits: Image by storyset