问题描述
在丹·阿布拉莫夫 (Dan Abramov) 的这个回答中,我发现了以下内容:
On this answer by Dan Abramov here on SO, I've found out the following:
目前(React 16 及更早版本),默认情况下仅对 React 事件处理程序内部的更新进行批处理. 有一个不稳定的 API 可以在您需要的极少数情况下强制在事件处理程序外部进行批处理.
他还在这个 Github 问题中提到了这一点:
He also mentions that in this Github issue:
https://github.com/facebook/react/issues/10231#issuecomment-316644950
在当前版本中,如果您在 React 事件处理程序中,它们将一起批处理. React 将在 React 事件处理程序期间完成的所有 setState 批处理,并在退出其自己的浏览器事件处理程序之前应用它们.
但事实是,这个片段似乎证明useEffect()
内多个 setState
调用的更新是批处理的.
But the fact is that this snippet seems to prove that updates for multiple setState
calls inside a useEffect()
are batched.
问题
React 是否也总是为 useEffect
内的多个 setState()
调用批量更新?它还有什么地方可以做到这一点?
Does React also always batch updates for multiple setState()
calls inside useEffect
? Where else does it do that ?
注意:根据他的回答,在下一个主要版本(可能是 v17)默认情况下,React 将在任何地方进行批处理.
NOTE: According to his answers, on next major release (probably v17) React will batch everywhere by default.
SNIPPET:在带有多个 setState()
调用的 useEffect()
内批量更新
SNIPPET: batch updates inside a useEffect()
with multiple setState()
calls
function App() {
console.log('Rendering app...');
const [myState,setMyState] = React.useState(0);
const [booleanState, setBooleanState] = React.useState(false);
console.log('myState: ' + myState);
console.log('booleanState: ' + booleanState);
React.useEffect(()=>{
console.log('Inside useEffect...');
setMyState(1);
setMyState((prevState) => prevState +1);
setMyState(3);
setMyState(4);
setMyState(5);
setBooleanState(true);
},[]);
return(
<div>App - Check out my console!</div>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
推荐答案
好问题.以下是完成@FranklinOcean 回答的其他信息.
Nice question. Here is additional info to complete @FranklinOcean answer.
2021 年更新:React 18 即将发生的变化
请参阅 React 18 中有关此主题的 Dan Abramov 更新,该主题添加了自动批处理:https://github.com/reactwg/react-18/discussions/21
Please see Dan Abramov update concerning this topic in React 18, which is the one that adds automatic batching: https://github.com/reactwg/react-18/discussions/21
回答当前版本的 react,即 17.0.2 及以下,截至 2021 年.
基于基于以下代码和框:
批量setStuff
调用:
Batched setStuff
calls:
- 同步内联组件功能块(我觉得相当于一个效果先于其他效果运行,没有依赖关系)
- 在一个
useEffect
块中同步 - 在合成事件处理程序中同步(由react管理,例如
onClick={handlerFunction}
)
- Inline the component function block synchronously (I think it is equivalent to having an effect running before the other effects and without dependencies)
- In a
useEffect
block synchronously - In a synthetic event handler synchronously (managed by react, such as
onClick={handlerFunction}
)
每次都会触发重新渲染的非批量调用:
- 任何异步代码(上述任何用例中的承诺/异步函数)
- 非合成事件(在 react lib 之外管理的事件)
- 这包括 XHR 或其他网络回调
我将尝试使用未来版本的 react 重新运行沙箱,看看效果如何!
I'll try re-run the sandbox with future versions of react to see how it goes!
这篇关于对 useEffect 钩子内的多个 setState() 调用进行批量更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!