跳至主要内容

鉤子 (Hooks) 的基礎知識

什麼是鉤子?

在 React 中,鉤子指的是可以在任何函式元件的頂層被呼叫的函式。在一個鉤子中,您可以做到任何在元件中可以做的事,並回傳任何數值 (或是不回傳任何東西) 來滿足您的需求。

信息
  • 您可能在想通用函式 (util function) 和鉤子之間有什麼區別,因為「可以在任何函式元件的頂層被呼叫的函式」這句話聽起來就像是在描述通用函式。一般來說,只要函式中使用了 React 才有的功能 (例如 useState() 或是 useEffect()),我們就會稱它為鉤子而不是普通的函式。
  • 單純從語法的角度來看,元件和鉤子之間其實沒有那麼不同。事實上,若您在一個鉤子中回傳 JSX 元素,那就會讓他變成一個元件而不是鉤子!

範例

舉例來說,如果我們有這樣一個函式:

const useLogger = () => {
const log = (value) => {
console.log('[Logger]', value)
}

const warn = (value) => {
console.warn('[Logger]', value)
}

return {
log,
warn,
}
}

在上方的程式碼中,我們宣告了一個 useLogger() 函式,他回傳一個有著兩個函式 log()warn() 的物件。傳統上,鉤子的名稱會以 use 開頭。雖然這個函式並沒有做任何特別的事情,但是他已經可以在元件中被作為鉤子使用了!例如:

import { useLogger } from './UseLogger'

export const Example = () => {
const { log, warn } = useLogger()

return (
// ...
)
}

就像這樣,您可以在鉤子中設計自己的系統,並在任何元件中重複使用他。在鉤子中,您可以隨意宣告變數和函式,依照需求更新他們,並選擇要匯出 (回傳) 哪些數值。回傳的數值不一定要是物件;您可以回傳一個數字、一個陣列、一個函式、甚至什麼都不回傳,一切都取決於您的設計。

React 提供許多內建的鉤子供我們使用。您可以直接在元件中使用他們,或是使用他們來建構您自己的鉤子。

注意事項

在鉤子的幫助下,我們現在能夠重複使用在整個應用程式中共享的功能,從而減少重複的程式碼。

然而,有一些重要的事情要記住:

  • 在製作鉤子時,重用性不是唯一需要考量的點。若某個元件的邏輯有點複雜,即使整個應用程式中只有一個元件在使用這個功能,將這個巨大的功能「切」(模組化) 成數個小功能 (鉤子) 也是完全沒問題的。如此一來,與將所有邏輯都放在同一個元件/鉤子中相比,我們的程式碼將變得更容易閱讀、維護及測試。
  • 元件並不是唯一一個能夠使用鉤子的地方;您也可以在鉤子中使用另外一個鉤子!
  • 更高的重用性不等於更好的程式碼!很多開發人員在面對新功能時會選擇修改既有的鉤子而不是製作一個新的,只為了讓他能夠在更多元件中被使用。在這種情況下,我們常常見到鉤子「失控」— 為了能處理各種(邊緣)情況,越來越多的參數和方法被加入,導致事情遠比它應有的還要複雜;而且隨著時間推移,重構/替換的成本只會越來越高。若您發現舊的鉤子開始變得過於複雜,不要害怕建立新的鉤子。