【发布时间】:2020-01-12 00:06:57
【问题描述】:
在 React 中,我们使用setState 来更新组件的状态。 setState 是一个异步进程,所以如果我们在同一个函数中有多个 setState。
问题:内部如何处理批量更新?
场景 1:
在 componentDidMount 的 for 循环中更新状态,但在同一执行周期中。
class TodoApp extends React.Component {
constructor(props) {
super(props)
var state = { count: 0 };
Object.defineProperty(this, 'state', {
set: function(value) { console.log('called', value.count); state = value },
get: function() { return state; }
})
}
test() {
for (let i = 0; i< 1000; i++) {
this.setState({ count: i });
}
}
componentDidMount() {
this.test();
}
render() {
return (
<div>
{ this.state.count }
</div>
)
}
}
ReactDOM.render(<TodoApp />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
场景 2:
在 componentDidMount 的 for 循环中更新状态,但执行周期不同。
class TodoApp extends React.Component {
constructor(props) {
super(props)
var state = { count: 0 };
Object.defineProperty(this, 'state', {
set: function(value) { console.log('called', value.count); state = value },
get: function() { return state; }
})
}
test() {
for (let i = 0; i< 1000; i++) {
this.setState({ count: i });
}
}
componentDidMount() {
setTimeout(this.test.bind(this), 0);
}
render() {
return (
<div>
{ this.state.count }
</div>
)
}
}
ReactDOM.render(<TodoApp />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
如果您注意到场景 1 和 2,则在场景 1 中仅执行 2 次更新(假设 1 用于初始更新,其他用于最终更新)。但是,在场景 2 中,每个 setState 的状态都会发生变化/更新。
那么异步更新是如何工作的?什么定义了批量更新操作?
【问题讨论】:
-
React 仅在同步以及在事件处理程序或生命周期方法中使用时批量更新状态。永远不会。
标签: javascript reactjs