javascript - 对 useEffect Hook 内的多个 setState() 调用进行 React 批量更新

标签 javascript reactjs react-hooks setstate use-effect

根据 Dan Abramov 在 SO 上的回答,我发现了以下内容:

Does React keep the order for state updates?

Currently (React 16 and earlier), only updates inside React event handlers are batched by default. There is an unstable API to force batching outside of event handlers for rare cases when you need it.

他还在这个 Github 问题中提到:

https://github.com/facebook/react/issues/10231#issuecomment-316644950

In current release, they will be batched together if you are inside a React event handler. React batches all setStates done during a React event handler, and applies them just before exiting its own browser event handler.

但事实是,这个片段似乎证明useEffect() 内的多个 setState 调用的更新是批处理的.

问题

React 是否也总是对 useEffect 内的多个 setState() 调用进行批量更新?它还在哪里做到这一点?

注意:根据他的回答,在下一个主要版本(可能是 v17)中,React 将默认在所有地方进行批处理。

SNIPPET:使用多个 setState() 调用在 useEffect() 内批量更新

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 答案的附加信息。

2021 年更新:React 18 即将发生的变化

请参阅 React 18 中有关此主题的 Dan Abramov 更新,该更新添加了自动批处理:https://github.com/reactwg/react-18/discussions/21

截至 2021 年当前版本的 React(17.0.2 及更低版本)的答案。

基于on the following codesandbox :

<小时/>

批量 setStuff 调用:

  • 同步内联组件功能 block (我认为这相当于让一个效果在其他效果之前运行并且没有依赖关系)
  • useEffect block 中同步进行
  • 在合成事件处理程序中同步(由 React 管理,例如 onClick={handlerFunction})
<小时/>

非批量调用每次都会触发重新渲染:

  • 任何异步代码(上述任何用例中的 Promise/异步函数)
  • 非合成事件(在 react 库外部管理的事件)
  • 其中包括 XHR 或其他网络回调
<小时/>

我将尝试使用 future 版本的 React 重新运行沙箱,看看效果如何!

关于javascript - 对 useEffect Hook 内的多个 setState() 调用进行 React 批量更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56885037/

相关文章:

javascript - Robots.txt 拒绝,对于 #!网址

javascript - 如何在 Typescript 库中导出子模块

javascript - 如何强制子组件重新渲染?

reactjs - 使用 React hooks 和 memo 时如何防止子组件重新渲染?

reactjs - 无法调用 useParams 钩子(Hook)

javascript - 从 NPM 安装 CRA 和 NextJS 时出现问题(错误 : Couldn't find package "@babel/core" on "npm" registry)

选中复选框时 JavaScript 启用按钮

javascript - 使用node js和react js的文件加载问题

reactjs - 首次加载时未显示 React Material Tabs 指示器

reactjs - 测试 react-redux useSelector