學 React 時,大家最常用的 hook 是 useEffect
,但有些場景用 useEffect
會出現畫面閃爍,這時候可能useLayoutEffect
也是一個選擇。那麼,這兩者的差別到底在哪裡?
useEffect
:在 DOM 更新並且瀏覽器完成 paint 後 才執行。
useLayoutEffect
:在 DOM 更新後、瀏覽器 paint 前 就會執行。
function Example() {
const ref = React.useRef(null);
React.useEffect(() => {
ref.current.style.backgroundColor = "yellow";
}, []);
return <div ref={ref}>Hello</div>;
}
➡️ 畫面會先出現原始顏色,再閃成黃色。
function Example() {
const ref = React.useRef(null);
React.useLayoutEffect(() => {
ref.current.style.backgroundColor = "yellow";
}, []);
return <div ref={ref}>Hello</div>;
}
➡️ 使用者一開始就看到黃色,不會跳動。
useLayoutEffect
」 → ❌ 會阻塞 paint,效能差。useEffect
也能量 DOM」 → ❌ 會拿到舊的畫面值,造成閃爍。useEffect
,只有需要同步 DOM 操作時才用 useLayoutEffect
。
CSS RWD 就好 → 一般排版切換,交給 media query,不需要 JS。
必須用 useLayoutEffect →
請判斷以下情境應該用哪個 hook:
useEffect
在瀏覽器 paint 後執行,適合非同步任務如資料請求或事件監聽。useLayoutEffect
在 paint 前執行,適合同步 DOM 操作,例如量測元素大小或避免畫面閃爍。
我通常預設用useEffect
,只有在需要同步 DOM 更新時才換成useLayoutEffect
。
useEffect
→ paint 後,適合非同步,不會阻塞畫面。useLayoutEffect
→ paint 前,適合同步 DOM 操作,避免閃爍。useEffect
,只有在需要精準控制 DOM 的時候才用 useLayoutEffect
。