关于 setState 的流程
-
自上而下执行组件(渲染阶段)
-
若遇到
useMemo,调用计算函数calculateValue,缓存计算结果; -
遇到微任务(如:
queueMicrotask、Promise.resolve().then()),将回调加入微任务队列; -
遇到宏任务(如:
setTimeout、setInterval等),将回调加入宏任务队列; -
提交渲染给浏览器(提交阶段):
-
执行
useLayoutEffect的回调; -
执行
useEffect的回调; -
查看微任务队列,若有任务,则执行微任务;
-
看看宏任务队列,若有任务,则执行宏任务;
-
若浏览器空闲,则执行
requestIdleCallback
- 自上而下执行事件处理函数
- 遇到微任务(如:
queueMicrotask、Promise.resolve().then()),将回调加入微任务队列; - 遇到宏任务(如:
setTimeout、setInterval等),将回调加入宏任务队列; - 遇到第一个
setState,执行setState回调,并开启一个queueMircoTask,将后续所有的setState回调装入一个队列; - 主线程空出,查看微任务队列,若有任务,则执行一个微任务;
- 渲染阶段
- 执行 state 的更新队列的 callback;
- 提交阶段
- 依次执行
useLayoutEffect的cleanup函数队列中的函数 - 执行
useLayoutEffect的回调; - 依次执行
useEffect的cleanup函数队列中的函数 - 执行
useEffect的回调; - 查看微任务队列(事件处理函数的剩余微任务、渲染阶段新生成的微任务),若有任务,则执行微任务;
- 看看宏任务队列(事件处理函数的宏任务、渲染阶段新生成的宏任务),若有任务,则执行宏任务;
- 若浏览器空闲,则执行
requestIdleCallback
- 依次执行
- 遇到微任务(如:
自上而下执行事件处理函数
- 执行第一个
setState前的微任务队列中的回调; - 渲染阶段
- 执行 state 的更新队列的 callback;
- 提交阶段
- 依次执行
useLayoutEffect的cleanup函数队列中的函数 - 执行
useLayoutEffect的回调; - 依次执行
useEffect的cleanup函数队列中的函数 - 执行
useEffect的回调; - 查看微任务队列(事件处理函数的剩余微任务、渲染阶段新生成的微任务),若有任务,则执行微任务;
- 看看宏任务队列(事件处理函数的宏任务、渲染阶段新生成的宏任务),若有任务,则执行宏任务;
- 若浏览器空闲,则执行
requestIdleCallback
- 依次执行