React 中,如何在 setState 之后调用某些函数执行操作,比如我用 reactflow.dev/ 设置了节点和边,然后想调用 fitView 让页面自适应。
我就会这样写代码,但是设置了一个 requestAnimationFrame。
setNodes([...layoutedNodes]);
setEdges([...layoutedEdges]);
requestAnimationFrame(() => {
fitView();
});
要想生效的使用两个 requestAnimationFrame,或者使用 setTimeout。
setNodes([...layoutedNodes]);
setEdges([...layoutedEdges]);
requestAnimationFrame(() => {
requestAnimationFrame(() => {
fitView();
});
});
这是为什么呢,我们来看看原因。
浏览器的渲染流水线是这样的:
setState 之后, React 会在下次更新,过程有点类似 useEffect,看看 useEffect 的渲染更新时间,useEffect 会在浏览器的重绘之后执行。
requestAnimationFrame 的渲染是这样的,下图的 rAf
整合一下就这样的:
原来 requestAnimationFrame 先于 React 的更新执行,第一次没效果所以需要执行两次,等待 React 更新完之后。
为什么 setTimeout 是有效的,因为 setTimeout 是一个任务,会放在任务队列中,等主线程任务执行完才会执行,React 的更新就是在主线程的,所以说白了就是等 React 更新完之后再执行 setTimeout,这就是 setTimeout 为什么会生效。
参考资料: