useEffect 和 useLayoutEffect 的區別

在 React hook 中,useEffect 用來取代 componentDidMount 和 componentDidUpdate。主要做用是當頁面渲染後,進行一些反作用操做(好比訪問 DOM,請求數據)。javascript

而 useLayoutEffect 的做用和 useEffect 幾乎差很少,你把你現有代碼的 useEffect 所有替換成 useLayoutEffect,你幾乎看不到任何差異。java

那它們的區別是什麼?看以下代碼:dom

function App() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    if (count === 0) {
      const randomNum = 10 + Math.random()*200
      setCount(10 + Math.random()*200);
    }
  }, [count]);

  return (
      <div onClick={() => setCount(0)}>{count}</div>
  );
}
複製代碼

11

運行上面的組件,點擊div,頁面會更新一串隨機數。ui

當你連續點擊時,你會發現這串數字在發生抖動。spa

緣由在於,當你每次點擊 div, count 會更新爲 0, 以後 useEffect 內又把 count 改成一串隨機數。code

因此頁面會先渲染成0,而後再渲染成隨機數,因爲更新很快,因此出現了閃爍。component

接下來咱們將 useEffect 改成 useLayoutEffect:cdn

function App() {
  const [count, setCount] = useState(0);
  
  useLayoutEffect(() => {
    if (count === 0) {
      const randomNum = 10 + Math.random()*200
      setCount(10 + Math.random()*200);
    }
  }, [count]);

  return (
      <div onClick={() => setCount(0)}>{count}</div>
  );
}
複製代碼

22

閃爍消失了。xml

相比使用 useEffect,當你點擊 div,count 更新爲 0,此時頁面並不會渲染,而是等待 useLayoutEffect 內部狀態修改後,纔會去更新頁面,因此頁面不會閃爍。blog

總結

  1. useLayoutEffect 相比 useEffect,經過同步執行狀態更新可解決一些特性場景下的頁面閃爍問題。
  2. useEffect 能夠知足百分之99的場景,並且 useLayoutEffect 會阻塞渲染,請謹慎使用。

Reference

When to useLayoutEffect Instead of useEffect

相關文章
相關標籤/搜索