iT邦幫忙

2025 iThome 鐵人賽

DAY 11
0
Modern Web

30 天掌握 React & Next.js:從基礎到面試筆記系列 第 11

Day 11:useEffect vs useLayoutEffect — 差別與使用時機

  • 分享至 

  • xImage
  •  

學 React 時,大家最常用的 hook 是 useEffect,但有些場景用 useEffect 會出現畫面閃爍,這時候可能useLayoutEffect也是一個選擇。那麼,這兩者的差別到底在哪裡?

概念解釋

  • useEffect:在 DOM 更新並且瀏覽器完成 paint 後 才執行。

    • 使用者會先看到畫面,再執行 effect。
    • 適合非同步行為(資料請求、事件監聽、log)。
  • useLayoutEffect:在 DOM 更新後、瀏覽器 paint 前 就會執行。

    • 使用者直接看到修改後的畫面,不會有閃爍。
    • 適合 DOM 操作(量測、定位、初始化動畫)。

範例程式碼

useEffect 可能造成閃爍

function Example() {
  const ref = React.useRef(null);

  React.useEffect(() => {
    ref.current.style.backgroundColor = "yellow";
  }, []);

  return <div ref={ref}>Hello</div>;
}

➡️ 畫面會先出現原始顏色,再閃成黃色。

useLayoutEffect 避免閃爍

function Example() {
  const ref = React.useRef(null);

  React.useLayoutEffect(() => {
    ref.current.style.backgroundColor = "yellow";
  }, []);

  return <div ref={ref}>Hello</div>;
}

➡️ 使用者一開始就看到黃色,不會跳動。

常見誤解

  1. 「所有副作用都該用 useLayoutEffect」 → ❌ 會阻塞 paint,效能差。
  2. useEffect 也能量 DOM」 → ❌ 會拿到舊的畫面值,造成閃爍。
  3. React 官方建議:預設用 useEffect,只有需要同步 DOM 操作時才用 useLayoutEffect

實務應用

  • CSS RWD 就好 → 一般排版切換,交給 media query,不需要 JS。

  • 必須用 useLayoutEffect

    • 元素寬高量測(決定動畫或排版)。
    • 初始化捲軸位置(例如聊天室滾動到底)。
    • 避免動畫初始閃爍(例如 fade-in)。
    • 與第三方 DOM library 整合(D3、GSAP)。

小練習

請判斷以下情境應該用哪個 hook:

  1. 畫面初始就要根據元素寬度決定排版。
  2. 頁面掛載時發送 API 請求。
  3. 新訊息出現時,聊天室自動滾動到底部。

面試回答模板

useEffect 在瀏覽器 paint 後執行,適合非同步任務如資料請求或事件監聽。
useLayoutEffect 在 paint 前執行,適合同步 DOM 操作,例如量測元素大小或避免畫面閃爍。
我通常預設用 useEffect,只有在需要同步 DOM 更新時才換成 useLayoutEffect

總結

  • useEffect → paint 後,適合非同步,不會阻塞畫面。
  • useLayoutEffect → paint 前,適合同步 DOM 操作,避免閃爍。
  • 預設用 useEffect,只有在需要精準控制 DOM 的時候才用 useLayoutEffect

上一篇
Day 10 : 什麼是 useEffect?
下一篇
Day 12:useState vs useReducer — 什麼時候該用哪一個?
系列文
30 天掌握 React & Next.js:從基礎到面試筆記13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言