首页 > 解决方案 > 为什么异步函数中的连续 setState 调用没有批处理?

问题描述

所以我知道 setState 调用是在 react 事件处理程序中批量处理以提高性能,但为什么我不明白为什么它们不批量处理异步回调中的 setState 调用。

例如:假设我在其中一个钩子中有以下代码。

fetch(url).then(res => res.json())
then((data)=>{
  setLoader(false);
  setData(data);
})

这两个 setState 调用将导致两个不同的渲染,即使它们在某种程度上是连续的或同步的。

我想了解为什么我们不能至少批处理这些彼此相邻的 setState 调用。这是由于技术限制还是选择不这样做的原因?

标签: javascriptreactjs

解决方案


这个问题讨论了 setState 何时被批处理,何时不是:

https://github.com/facebook/react/issues/14259

总结一下:

如果从基于 React 的事件中触发状态更新,例如按钮单击或输入更改,React 当前将批处理状态更新。如果它们是在 React 事件处理程序之外触发的,它不会批量更新,比如 setTimeout()。

React 将您的事件处理程序包装在对不稳定批处理更新()的调用中,以便您的处理程序在回调中运行。在该回调中触发的任何状态更新都将被批处理。在该回调之外触发的任何状态更新都不会被批处理。超时、承诺和异步函数最终将在该回调之外执行,因此不会被批处理。

该线程还对如何使用useReducer而不是解决这个“问题”提出了一些建议useState。这是一个示例,尽管我还没有尝试过它是否可以工作:

const [ state, dispatch, batch ] = useReducer(reducer, initialState);

batch(() => {
  dispatch(..);
  dispatch(..);
  // etc..
})

推荐阅读