javascript - 为什么异步函数中的连续 setState 调用没有批处理?
问题描述
所以我知道 setState 调用是在 react 事件处理程序中批量处理以提高性能,但为什么我不明白为什么它们不批量处理异步回调中的 setState 调用。
例如:假设我在其中一个钩子中有以下代码。
fetch(url).then(res => res.json())
then((data)=>{
setLoader(false);
setData(data);
})
这两个 setState 调用将导致两个不同的渲染,即使它们在某种程度上是连续的或同步的。
我想了解为什么我们不能至少批处理这些彼此相邻的 setState 调用。这是由于技术限制还是选择不这样做的原因?
解决方案
这个问题讨论了 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..
})
推荐阅读
- html - 将值从一个表传递到另一个 html 页面
- c++ - 如何使用中值滤波算法去除胡椒噪声
- c++ - 在 if 语句中声明时如何访问类对象?(在 C++ 中)
- java - java - 如何在java swing中加载本地html文件?
- centos7 - Clearcase - 无法访问 VOB - ls:读取目录 - 权限被拒绝
- android - 如何在 viewpager 中使用 webview 的水平滚动?
- swift - 文本文件中的 Swift 转换格式(字符串解析)
- spring-boot - spring boot配置自定义sql
- c# - 如何获取列表框中所选项目的索引值?
- android - 使用 DownloadManager 下载视频文件时,应用程序在 Android 10 上崩溃