Jeff的隨手筆記

學習當一個前端工程師

0%

『Day 30』移除 Effect 的依賴項

前言

還記得我一開始學習 React 時,總是習慣性地調整依賴陣列來解決問題,想當然爾地認為:「反正只要控制好依賴,Effect 就會按照我想要的次數執行」。但隨著開發經驗的累積,漸漸明白到這樣的思維其實不太正確。

這種做法雖然在短期內看似解決了問題,但往往會埋下一些難以發現的 bug。今天就讓我來分享一下,在實務上我們該如何處理 Effect 的依賴問題。

Effect 依賴的本質

在深入討論之前,我們必須先理解一個重要的概念:Effect 的依賴是由程式碼本身決定的,而不是由我們主觀決定想要執行幾次。這就像是在寫數學公式,如果公式中用到了某個變數,那這個變數就必然會影響結果。

讓我們看一個簡單的例子:

1
2
3
4
5
6
7
8
function ChatRoom({ roomId }) {  // roomId 是響應式的值
useEffect(() => {
const connection = createConnection(roomId); // Effect 使用了這個值
connection.connect();
return () => connection.disconnect();
}, [roomId]); // 所以必須加入依賴陣列
}

如何移除不必要的依賴?

當我們發現 Effect 因為某些依賴而過度執行時,應該從調整程式碼結構開始著手,而不是強制忽略這些依賴。以下分享幾個實用的技巧:

1. 確認是否真的需要使用 Effect

很多時候,我們其實不需要使用 Effect。特別是在處理事件回應時,直接使用事件處理函式會是更好的選擇:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ❌ 不建議的寫法
function Form() {
useEffect(() => {
if (submitted) {
api.submitForm(data);
}
}, [submitted]);
}

// ✅ 建議的寫法
function Form() {
function handleSubmit() {
api.submitForm(data);
}
}

2. 將相關邏輯移至 Effect 內部

如果某個依賴項(特別是物件或函式)造成不必要的重新執行,考慮將它移到 Effect 內部:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// ❌ 不建議的寫法
function ChatRoom({ serverUrl, roomId }) {
const options = {
serverUrl,
roomId
};

useEffect(() => {
const connection = createConnection(options);
}, [options]); // options 每次重新渲染都會是新的物件

// ✅ 建議的寫法
function ChatRoom({ serverUrl, roomId }) {
useEffect(() => {
const options = {
serverUrl,
roomId
};
const connection = createConnection(options);
}, [roomId, serverUrl]); // 只依賴實際需要的值
}

3. 從物件中提取基本型別的值

當從 props 收到物件時,可以先解構出實際需要的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// ❌ 不建議的寫法
function ChatRoom({ options }) {
useEffect(() => {
const connection = createConnection(options);
}, [options]); // options 物件可能經常變動

// ✅ 建議的寫法
function ChatRoom({ options }) {
const { roomId, serverUrl } = options;
useEffect(() => {
const connection = createConnection({
roomId,
serverUrl
});
}, [roomId, serverUrl]); // 只依賴實際需要的值
}

重要提醒

在處理 Effect 依賴時,有幾點特別要注意:

  1. 不要忽視 ESLint 的警告:這些警告通常代表潛在的問題,應該認真看待
  2. 依賴陣列反映程式碼的實際需求:它不是用來控制執行時機,而是用來確保同步機制的正確性
  3. 重構優於強制:如果發現依賴太多,應該思考如何重構程式碼,而不是強制移除依賴

總結

理解並正確處理 Effect 的依賴關係,是寫出優質 React 程式碼的關鍵之一。記住,當我們遇到依賴相關的問題時,應該從調整程式碼結構開始著手,而不是試圖透過修改依賴陣列來「控制」Effect 的行為。這樣不只能讓程式碼更容易維護,也能避免許多潛在的問題。