Hooks 簡介
Hooks 簡介
Hooks 是 React 16.8 引入的一個功能,它允許你在函數型組件(Functional Components)中使用狀態(state)和其他 React 功能,而不需要使用類別組件(Class Components)。這使得函數型組件能夠更靈活且簡潔地實現狀態管理、生命週期操作等功能。
Hooks 的特點
- 完全向後兼容:你可以逐步在現有項目中引入 Hooks,而不會對現有代碼產生影響。
- 不會破壞類別組件:類別組件仍然可以繼續使用,但 Hooks 提供了一種更簡潔的方式來處理相同的功能。
- 減少複雜性:在不需要寫類別的情況下,可以實現狀態管理和副作用處理,使代碼更加直觀。
1. 使用狀態的 Hook:useState
useState
是最常見的 Hook,用於在函數型組件中添加狀態。
基本語法:
1
const [state, setState] = useState(initialState);
state
:是當前狀態的值。setState
:是一個函數,用來更新狀態。initialState
:是狀態的初始值,可以是任意數據類型。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // 定義一個 count 狀態,初始值為 0
return (
<div>
<p>當前計數: {count}</p>
<button onClick={() => setCount(count + 1)}>增加</button>
</div>
);
}
export default Counter;
在這個範例中:
useState(0)
初始化了一個count
狀態,初始值為0
。- 當按鈕被點擊時,調用
setCount
函數將count
加1
,從而觸發組件重新渲染。
2. 處理副作用的 Hook:useEffect
useEffect
用來在函數型組件中執行副作用操作,比如數據請求、訂閱和手動 DOM 操作。這相當於類別組件中的 componentDidMount
、componentDidUpdate
和 componentWillUnmount
。
基本語法:
1
2
3
4
5
6
useEffect(() => {
// 副作用操作,例如數據請求
return () => {
// 可選的清理操作
};
}, [dependencies]);
- 副作用操作:在組件渲染後執行的操作。
- 清理操作:用來清理之前的副作用,比如移除事件監聽器。這個函數會在組件卸載時或依賴項變化之前執行。
[dependencies]
:依賴項數組。只有當數組中的某些值發生改變時,useEffect
內的副作用操作才會重新執行。如果不傳入依賴項,副作用會在每次渲染後執行。如果依賴項數組為空,副作用只會在掛載和卸載時執行一次。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React, { useState, useEffect } from 'react';
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setCount(prevCount => prevCount + 1);
}, 1000);
return () => clearInterval(interval); // 清除計時器,避免內存泄漏
}, []);
return <p>計時器: {count}</p>;
}
export default Timer;
在這個範例中:
useEffect
設置了一個計時器,每秒增加一次計數器。return
語句返回了一個清理函數,用來在組件卸載時清除計時器,防止內存洩漏。
3. 更多常用 Hooks
除了 useState
和 useEffect
,React 還提供了其他有用的內建 Hooks:
useContext
useContext
用來在函數型組件中讀取上下文(context)數據,而不需要用 Context.Consumer
或 this.context
。
1
const value = useContext(MyContext);
useReducer
useReducer
是 useState
的替代方案,適合處理更複雜的狀態邏輯(例如管理多個相關狀態)。
1
const [state, dispatch] = useReducer(reducer, initialState);
useRef
useRef
用來存儲可以在渲染間保持不變的可變值,或直接訪問 DOM 元素。
1
const inputRef = useRef(null);
useMemo
和 useCallback
useMemo
用於優化性能,避免在每次渲染時進行昂貴的計算。useCallback
用於緩存函數,避免不必要的函數重新創建,適合傳遞給子組件的函數。
4. 自定義 Hooks
除了內建的 Hooks,React 允許你創建自定義 Hooks,這使得我們可以將組件邏輯進行封裝和重用。自定義 Hooks 就是一個以 “use” 開頭的普通函數,它可以使用其他 Hooks 並返回一些值。
範例:自定義 useFetch
Hook
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then((response) => response.json())
.then((data) => {
setData(data);
setLoading(false);
});
}, [url]);
return { data, loading };
}
export default useFetch;
這個自定義 useFetch
Hook 封裝了數據請求邏輯,我們可以在不同的組件中重複使用它。
5. Hooks 的規則
使用 Hooks 時有兩個重要的規則:
- 只能在函數最頂層調用 Hooks:不要在循環、條件或嵌套函數中調用 Hooks,這是為了確保 Hooks 按照相同的順序執行。
- 只能在 React 函數組件或自定義 Hook 中使用 Hooks:不要在普通的 JavaScript 函數中使用 Hooks。
總結
Hooks 是 React 中強大的功能,使得我們能夠在函數型組件中使用狀態、生命週期和其他功能,並且可以更好地重用邏輯。useState
和 useEffect
是最常用的 Hooks,通過它們,我們可以實現大部分狀態管理和副作用處理的需求。隨著自定義 Hooks 的引入,開發者可以將複雜邏輯進行封裝和重用,使得代碼更加清晰易讀。