参考大佬的文章:https://www.jianshu.com/p/5296c5acf788
摘要:
在React
通知到Renderer
渲染器后,渲染器又分了三个子阶段来处理:
beforeMutation
阶段(渲染视图前)mutation
阶段(渲染试图)layout
阶段(渲染视图后)
渲染器会在mutation
阶段完成后, 在layout
阶段同步的调用useLayoutEffect
,在子组件嵌套中于是如此。在类组件中,调用的是componentDidMount
生命周期函数。也就是说,在useLayoutEffect
中,无论是否有重新触发setState
,也不会在当前渲染里,重新更新界面。
而在整个渲染器渲染阶段(其实也叫commit
)渲染完成后,react
才会异步的执行useEffect
。当在useEffect
中如果有setState
,则会重新触发渲染器,更新界面。
结论:
useLayoutEffect
的是在渲染器执行当前渲染界面任务时,同步执行。- 在当前一轮的
Reconciler
任务调度过程中,在渲染器执行完当前任务后,才会异步调用useEffect
。 useLayoutEffect
先于useEffect
执行,并且子组件优先执行。componentDidMount()
完全等价于useLayoutEffect( fn , [ ] )
,但是不等价于useEffect( fn , [ ] )
。