我记得当我发现 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/