布局副作用
- useEffect在浏览器渲染完成后执行
- useLayoutEffect在浏览器渲染前执行
特点
- useLayoutEffect总是比useEffect先执行
- 使用useLayoutEffect时,里面的任务最好影响了 Layout ,否则会占用等待时间
经验
- 为了用户体验,优先使用useEffect(优先渲染),因为大部分时候,我们不会去改变DOM
- useLayoutEffect会影响用户看到画面变化的时间
function App() {
const [n, setN] = useState(0)
useEffect(()=>{
document.querySelector('#App').innerText = `n: 1000`
},[n])
return (
<div id="App">
n:{n}
</div>
);
}
因为useEffect在render之后调用,页面会有一个从0变成1000的短暂闪烁
![]()
function App() {
const [n, setN] = useState(0)
useLayoutEffect(()=>{
document.querySelector('#App').innerText = `n: 1000`
},[n])
return (
<div id="App">
n:{n}
</div>
);
}

正常情况下,DOM操作很多,等DOM操作完,再去渲染,useLayoutEffect在渲染前,改变DOM
useEffect和useLayoutEffect的时序
function App() {
const [n, setN] = useState(0)
const time = useRef(null)
const onClick = () => {
setN(i => i + 1)
time.current = performance.now()
}
useEffect(() => {
if(time.current){
console.log('useEffect时序')
console.log(performance.now()-time.current)
}
})
useLayoutEffect(() => {
if(time.current){
console.log('useLayoutEffect时序')
console.log(performance.now()-time.current)
}
})
return (
<div className="App">
n:{n}
<button onClick={onClick}>+1</button>
</div>
);
}
image.png
网友评论