在學習 React 的過程中,useEffect
是許多初學者常常感到困惑的一個 Hook。今天的筆記會記錄一下:
useEffect
的基本概念- 使用時機
- 潛藏陷阱
🔍 Effect 是什麼?
Effect(副作用)是指 除了 return 值之外還會與外部互動或產生更大影響的行為。這些通常包含:
- 向伺服器發送資料(如 API 請求)
- 註冊事件監聽器(如 `window.addEventListener``)
- 操作 DOM(例如
document.title = "..."
) - 設定或清除定時器(如
setTimeout
,setInterval
)
這些副作用行為通常會超出 React 元件本身的範疇,因此 React 提供了 useEffect
來集中管理這些副作用。
⚠️ Effect 可能造成的問題
如果沒有妥善管理 effect 的執行與清除,可能會出現以下問題:
- 記憶體洩漏:例如註冊了事件但沒清除
- 多次重複執行:依賴沒寫齊,導致每次 render 都重新執行
- 畫面狀態錯亂:例如過時的資料仍被使用,造成顯示不一致
- 效能低落:頻繁 re-render 導致效能下降
💡 useEffect
是什麼?
useEffect
是 React 中用來處理副作用的 Hook。它的主要功能有兩個:
- 執行副作用程式碼:如前述的 API 呼叫、DOM 操作等。
- 清除副作用:透過
useEffect
傳回的清除函式(cleanup function),可以在元件 unmount 或重新執行 effect 前清除先前的副作用,避免記憶體洩漏或非預期行為。
|
|
🛠️ useEffect
的用法
基本語法如下:
|
|
📌 根據依賴的不同,行為會有所差異:
useEffect(someActions)
:沒有指定依賴陣列,每次 render 都會執行,即使狀態沒改變也一樣useEffect(someActions, [])
:傳入空陣列作為依賴,在第一次 render 時執行一次,後續 re-render 時會被安全的跳過useEffect(someActions, [foo, bar])
:傳入依賴陣列,當 foo 或 bar 的值改變時才會重新執行 effect
❗安全的跳過 ≠ 保證會跳過
很多人會誤以為傳入 []
就一定不會重新執行,但實際上:
- 安全地跳過是指跳過沒問題、不跳過也沒問題:有時候依賴沒列齊(例如漏掉某個 context 或 props),會導致效果不如預期
- dependencies 是效能優化的手段,而不是執行時機的主邏輯控制工具
最好的做法是:
寫出正確的 effect 邏輯,然後再優化 dependencies。