useLayoutEffect
的描述Reactjs文檔裏這樣描述useLayoutEffect
:html
The signature is identical to
useEffect
, but it fires synchronously after all DOM mutations
only differs in when it is fired
即useLayoutEffect
跟useEffect
函數簽名一致,可是在DOM修改後同步觸發,這是和useEffect
惟一的區別。react
useLayoutEffect
?假設有個展現隨機數字的case,當count
爲0時隨機生成個數字:git
useEffect
實現:import { useState, useEffect, useLayoutEffect } from 'react' export default function App() { const [count, setCount] = useState(0); useEffect(() => { console.log(`useEffect - count=${count}`) // 耗時的操做 const pre = Date.now(); while(Date.now() - pre < 500) {} // count爲0時從新生成個隨機數 if (count === 0) { setCount(10 + Math.random() * 200); } }, [count]); // 點擊DIV重置count return ( <div onClick={() => setCount(0)}>{count}</div> ); }
能夠看到展現0的過程。github
useLayoutEffect
實現:import { useState, useEffect, useLayoutEffect } from 'react' export default function App() { const [count, setCount] = useState(0); useLayoutEffect(() => { console.log(`useLayoutEffect - count=${count}`) // 耗時的操做 const pre = Date.now(); while(Date.now() - pre < 500) {} if (count === 0) { setCount(10 + Math.random() * 200); } }, [count]); return ( <div onClick={() => setCount(0)}>{count}</div> ); }
沒有閃爍,當點擊 div,count 更新爲 0,此時頁面並不會渲染,而是等待useLayoutEffect
內部狀態修改後,纔會去更新頁面,因此頁面不會閃爍。瀏覽器
Updates scheduled inside
useLayoutEffect
will be flushed synchronously, before the browser has a chance to paint
useLayoutEffect
會阻塞瀏覽器渲染,正好本例中useLayoutEffect
的實參函數裏有個耗時操做,因此頁面更新比較卡頓。useLayoutEffect
和componentDidMount
、componentDidUpdate
觸發時機一致上面的例子改用class
組件實現試試:dom
import React from 'react' export default class App extends React.Component { constructor(props) { super(props); this.state = { count: 0 } } componentDidUpdate() { // 耗時的操做 const pre = Date.now(); while(Date.now() - pre < 500) {} } increaseCount = () => { this.setState(({ count }) => { return { count: count + 1} }) } render() { const { count } = this.state; return ( <div onClick={this.increaseCount}>{count}</div> ) } }
跟useLayoutEffect
效果同樣:也是看不到閃爍,但也比較卡頓。ide
useLayoutEffect
和componentDidMount
和componentDidUpdate
觸發時機一致(都在在DOM修改後且瀏覽器渲染以前);useLayoutEffect
要比useEffect
更早的觸發執行;useLayoutEffect
會阻塞瀏覽器渲染,切記執行同步的耗時操做。除非要修改DOM而且不讓用戶看到修改DOM的過程,才考慮使用useLayoutEffect
,不然應當使用useEffect
。函數
注意:若是隻是爲了獲取DOM屬性(或其它get操做),則不必使用useLayoutEffect
,應當使用useEffect
。this
整理自gitHub筆記useEffect
和useLayoutEffect
到底有什麼區別?spa