useLayoutEffect看起来和useEffect非常的相似;事实上,他们也仅有一点区别而已;
- useEffect:渲染内容更新到DOM ->执行操作;
- useLayoutEffect:执行操作 -> 渲染内容更新到DOM;
如果我们希望在某些操作发生之后再更新DOM,那么应该将这个操作放到useLayoutEffect中。

useEffect & useLayoutEffect流程
先拿之前的useEffect举例。
- 点击按钮后触发setCount(0),重新渲染;
- 重新渲染后,检测到count改变,所以触发useEffect回调函数,再次调用setCount(Math.random()),界面又会重新渲染,这次将随机数渲染(第二次渲染)出来;
- 上次渲染后,count改变,再次触发useEffect,但count不再等于0,所以这次不再执行setCount(Math.random())。
import React, { useState, useEffect } from 'react'
export default function EffectCounterDemo() {
const [count, setCount] = useState(10);
useEffect(() => {
if (count === 0) {
setCount(Math.random() + 200);
}
}, [count])
return (
<div>
<h2>数字: {count}</h2>
<button onClick={e => setCount(0)}>修改数字</button>
</div>
)
}
如果我们想将最终值一次性渲染出来,就需要用到useLayoutEffect hook了。
useLayoutEffect举例
只需要将useEffect改成useLayoutEffect即可。
官网提到的一些应该注意的点:
- 应先使用useEffect,若出问题再尝试useLayoutEffect;
- useLayoutEffect与componentDidMount,componentDidUpdate的调用阶段是一样的;
- 针对服务端渲染:useEffect和useLayoutEffect都无法在JS代码加载完成之前执行。(笔者暂未接触服务端渲染,日后补上具体细节)