iT邦幫忙

2025 iThome 鐵人賽

DAY 10
0

在 React function component 中,常常需要處理 副作用 (side effects),例如:

  • 抓 API 資料
  • 綁定或移除事件(scroll, resize...)
  • 操作 DOM
  • 設定計時器

在 class component 時代,這些通常寫在 componentDidMountcomponentDidUpdatecomponentWillUnmount
在 function component 中,React 提供的解法就是 useEffect

定義

useEffect 是一個 Hook,讓你在 render 結束、DOM 更新完成後 執行副作用,並在需要時進行清理。

語法:

useEffect(() => {
  // 副作用邏輯
  return () => {
    // 清理邏輯 (可選)
  };
}, [dependencies]);
  • 副作用函數:要做的工作
  • cleanup 函數:釋放資源、解除事件等
  • 依賴陣列:決定什麼時候要重新執行

setState 與 useEffect 的執行時機

當我們呼叫 setState 時,React 的流程大致如下:

  1. setState 觸發 → 排程一次 re-render
  2. Render 階段 → 執行 component function,產生新的 Virtual DOM
  3. Commit 階段 → React 把差異套用到真實 DOM,畫面更新
  4. useLayoutEffect(同步) → 在瀏覽器繪製前執行
  5. 瀏覽器繪製 (paint) → 使用者看到更新後的畫面
  6. useEffect(非同步) → 在畫面繪製之後執行

畫面會先更新,再執行 useEffect

依賴陣列的三種情況

  1. 沒有依賴陣列 → 每次 render 都執行
  2. 空陣列 [] → 只在第一次 render 後執行
  3. 有依賴 [state] → 當依賴值改變時執行

Cleanup 機制

useEffect 可以回傳一個 cleanup 函數:

  • 下一次 effect 執行前component unmount 時呼叫
  • 常見用途:移除事件監聽、清除計時器
useEffect(() => {
  const handler = () => console.log("resize");
  window.addEventListener("resize", handler);

  return () => {
    window.removeEventListener("resize", handler);
  };
}, []);

常見誤解

  1. 在 render 裡直接打 API → 應該放進 useEffect
  2. 忘記 cleanup → memory leak
  3. 依賴陣列寫錯 → stale data / 無限迴圈
  4. 在 effect 無條件 setState → 觸發無限重渲染

面試

useEffect 是 React function component 中處理副作用的 Hook。
當呼叫 setState 時,React 會先 re-render,然後更新 DOM,畫面繪製完成後才執行useEffect
這讓我們可以安全地處理 API、事件監聽或計時器,並透過 cleanup 做好清理。
如果需要在畫面繪製前就同步操作 DOM,則使用 useLayoutEffect

useEffect is the Hook for running side effects in function components.
When you call setState, React first re-renders and updates the DOM.
The browser paints the UI, and only then useEffect runs.
This makes it safe for tasks like fetching data or setting up listeners.
If you need to manipulate the DOM before paint, you should use useLayoutEffect.

總結

  • useEffect = function component 的副作用管理器
  • 執行時機 → render 後、畫面更新後
  • 三種依賴模式:每次 / 一次 / 依賴改變時
  • 支援 cleanup → 清理資源

上一篇
Day 9 : 為什麼 Hooks 一定要寫在最上層
系列文
30 天掌握 React & Next.js:從基礎到面試筆記10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言