1. 程式人生 > 實用技巧 >React中useLayoutEffect和useEffect的區別

React中useLayoutEffect和useEffect的區別

重點: 1.二者函式簽名相同,呼叫方式是一致的

   2. 怎麼簡單進行選擇: 無腦選擇useEffect,除非執行效果和你預期的不一致再試試useLayoutEffect

區別詳解:
useEffect是非同步執行,而且是在渲染被繪製到螢幕之後執行。
流程如下:
你以某種方式觸發了rerender(改變state,或者父元件發生rerender)
React渲染你的元件(呼叫元件函式)
螢幕在視覺上更新(真實dom操作)
然後useEffect執行

useLayoutEffect是同步執行,時機在渲染之後但在螢幕更新之前。

流程如下:
你以某種方式觸發了rerender(改變state,或者父元件發生rerender)
React渲染你的元件(呼叫元件函式)
useLayoutEffect執行,React等待它完成
螢幕在視覺上更新(真實dom操作)

程式碼實戰

const BlinkyRender = () => {
  const [value, setValue] = useState(0);

  useLayoutEffect(() => {
    if (value === 0) {
      setValue(10 + Math.random() * 200);
    }
  }, [value]);

  console.log('render', value);

  return (
    <div onClick={() => setValue(0)}>
      value: {value}
    
</div> ); };


當點選div時,狀態立即改變(value重置為0),這將重新Render元件,然後執行Effect——將值設定為某個隨機數,並再次重新Render。


也就是是兩次Rerender會快速連續發生。分別換用useLayoutEffect和useEffect觀察有什麼不同。

你會發現useLayoutEffect的版本會在元件render兩次的情況下僅在視覺上更新一次。而useEffect版本在視覺上也會呈現兩次,所以會看到閃爍,從0閃爍變成對應的隨機數。

所以到底什麼時候使用useLayoutEffect呢?

如果你的元件在狀態更新時閃爍,比如它首先以部分就緒狀態呈現,然後立即以最終狀態重新呈現——這是一個很好的線索,是時候換useLayoutEffect了。

當您的更新是兩步(或多步)過程時,就會出現這種情況。你想在重新繪製螢幕之前一起批處理多個更新嗎,試試useLayoutEffect。

在大多數情況下,你的effect函式會在對應的依賴項如state或props改變時執行,而對應的回撥邏輯往往不會立即影響或根本不影響頁面視覺。
比如發一個ajax請求
或者你設定一個了事件處理器


大多數時候,使用useEffect是正確的。如果您的程式碼導致閃爍,切換到useLayoutEffect,看看是否有幫助。


因為useLayoutEffect是同步的,也就是阻塞的,在你的effect執行完之前,視覺不會更新。如果你的effect中有計算密集型程式碼,它可能會導致效能體驗問題,比如卡頓。大多數effect在執行時並不需要"stop the world",普通的 useEffect幾乎可以滿足我們所有的需求。