为什么异步函数中的连续setState调用不批处理?

时间:2019-09-04 04:52:02

标签: javascript reactjs

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

例如: 假设我在其中一个挂钩中包含以下代码。

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

这两个setState调用将导致两个不同的渲染,即使它们以某种方式彼此连续或同步。

我想了解为什么我们不能批量处理彼此相邻的setState调用,这是由于技术限制还是有理由选择不这样做?

1 个答案:

答案 0 :(得分:2)

此问题讨论何时批处理setState和何时不批处理:

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

总结:

  

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

     

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

该线程还提供一些建议,说明如何使用useReducer而不是useState解决这个“问题”。这是一个示例,尽管我没有尝试过看看是否可行:

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

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