reactjs - 多个 setState 不会累积到一次更新/渲染中...?

标签 reactjs

我记得当我发现 setState 是异步的时我是多么惊讶。现在我偶然发现了一种“奇怪”的行为,它不符合我对 setState 异步性的理解。

考虑下面的代码片段(由于某种原因,它会导致脚本错误,这里是外部沙箱:https://codesandbox.io/s/zwrvkz74y3):

class SomeComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      prop1: 1,
      prop2: 2
    };

    setTimeout(this.changeProp1.bind(this), 100);
  }

  componentDidUpdate() {
    console.info("componentDidUpdate called");
  }

  changeProp1() {
    this.setState({ prop1: 2 });
    this.changeProp2();
  }

  changeProp2() {
    this.setState({ prop2: 3 });
  }

  render() {
    const { prop1, prop2 } = this.state;
    return React.createElement('div', null, `prop1: ${prop1}, prop2: ${prop2}`);
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(React.createElement(SomeComponent), rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

如果您运行此命令并检查控制台,您将看到 componentDidUpdate 被调用了两次,但是 setStates 不应该累积并更新组件一次吗?

更新:我认为我的困惑来自State Updates May Be Asynchronous中的这句话。 ReactJS 网站上的部分:

React may batch multiple setState() calls into a single update for performance.

最佳答案

正如引用文献的链接部分所述,

React may batch multiple setState() calls into a single update for performance.

不应该批量更新状态,至少在 React 16 中是这样。

正如 React 团队的 Dan Abramov 在 related answer 中广泛解释的那样,状态当前仅从事件监听器批量更新,也在生命周期 Hook 中的同步 setState 调用 (componentDidMount) >,componentDidUpdate)。预计这将在 React 17 中改变。

在 React 16 中,应显式使用 unstable_batchedUpdates 来无条件批量更新状态(demo):

setTimeout(() => {
  ReactDOM.unstable_batchedUpdates(() => {
    this.changeProp1();
  });
}, 100);

关于reactjs - 多个 setState 不会累积到一次更新/渲染中...?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52025308/

相关文章:

javascript - 如何通过在该上下文类中的方法中创建的 onClick 函数传递 React 上下文的状态?

reactjs - react 弹出后"process is not defined"错误

javascript - 不包含名为

javascript - 如何在 react-styleguidist 中添加具有依赖关系的组件示例

reactjs - Firebase - 预检响应中的 Access-Control-Allow-Headers 不允许请求 header 字段 x-firebase-gmpid

reactjs - KeyboardDateTimePicker Material UI 非空验证

reactjs - 更改 Material UI Chip 主要或次要颜色

javascript - React - 在同一文件中导出多个类

javascript - CSS/JavaScript - 当用户开始滚动时滚动捕捉

reactjs - react Redux : 'X is not a function' after using mapDispatchToProps