ReactJS - 使用 useCallback:初學者指南
您好,未來的 React 開發者!今天,我們將深入探討 React 的強大 Hooks 之一:useCallback
。別擔心你對編程還是新手;我會逐步引導你了解這個概念,就像我過去幾年來對許多學生所做的一樣。讓我們一起踏上這個令人興奮的旅程吧!
useCallback 是什麼?
在我們深入了解之前,讓我們先了解 useCallback
的相關知識。想像一下你正在烤餅乾(我喜歡這個比喻,因為,好吧,誰會不喜歡餅乾呢?)你有一個每次都會使用的特別配方。useCallback
就像寫下那個配方一次,並在每次需要烤餅乾時使用它,而不是每次都試圖記住它。
在 React 的術語中,useCallback
是一個 Hook,它通過記憶(memoization)函數來幫助我們優化應用程序的性能。
useCallback Hook 的語法
讓我們看看如何寫 useCallback
:
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
別慌張!我知道這可能看起來很複雜,但我們會一一解析:
-
memoizedCallback
:這是useCallback
返回的函數。 -
() => { doSomething(a, b); }
:這是我們想要記憶的函數。 -
[a, b]
:這被稱為依賴數組。它告訴 React 什麼時候重新創建我們的函數。
把它想成這樣:你正在告訴 React,“嘿,記住這個函數對我來說,而且只有當 a
或 b
變化時才給我一個新的。”
使用 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>
);
}
讓我們來解析這個例子:
- 我們從 React 中導入
useCallback
。 - 我們使用
useState
創建一個狀態變量count
。 - 我們使用
useCallback
定義一個increment
函數。這個函數會將我們的計數增加 1。 - 空數組
[]
作為第二個參數意味著這個函數從不會變化。 - 我們渲染我們的計數和一個按鈕,當點擊時會調用
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