我有下面一段代码 -
class Sum extends React.Component {
constructor(props) {
super(props)
this.state = { a : 0 }
}
// let's call this ADD-1
add = () => {
this.setState({ a: this.state.a + 1 })
this.setState({ a: this.state.a + 2 })
this.setState({ a: this.state.a + 3 })
}
render() {
return (<div>
<button onClick={this.add}> click me </button>
<div> sum {this.state.a} </div>
</div>)
}
}
点击按钮后呈现
sum = 3
我希望它会呈现 sum = 6
即 1 + 2 + 3
此外,如果我将我的 add
方法更改为类似适应 prevState
竞争条件的方法 -
// let's call this ADD-2
add = () => {
this.setState({ a: this.state.a + 1 })
this.setState({ a: this.state.a + 2 })
this.setState(prevState => ({ a: prevState.a + 1 }))
this.setState(prevState => ({ a: prevState.a + 4 }))
}
它呈现 sum = 7
而我希望 sum = 8
即 (1 + 2 + 1 + 4)
现在我想到两个问题:-
1) 为什么我们看到的结果是上面提到的结果,而不是我预期的结果?
2) 为什么我在 UI 中看不到添加的过渡?
假设我们考虑标记为 ADD-1
的方法,我应该看到类似 sum = 1
然后 sum = 3
然后 sum = 6
。是因为批处理更新但批处理将它们放入执行队列中,我认为它不会覆盖任何内容。
最佳答案
状态更新可能是异步的。检查这个answer .
在 answer 中Dan abramov 指出,一次事件调用中的状态更新只会在事件结束时产生一次重新渲染。
no matter how many setState() calls in how many components you do inside a React event handler, they will produce only a single re-render at the end of the event.
而且批处理只发生在 React 事件处理程序中的状态更新,即批处理不会发生在 AJAX 调用中
promise.then(() => {
// We're not in an event handler, so these are flushed separately.
this.setState({a: true}); // Re-renders with {a: true, b: false }
this.setState({b: true}); // Re-renders with {a: true, b: true }
this.props.setParentState(); // Re-renders the parent
});
但是您可以通过将回调传递给 setState
方法来实现您想要的效果
add = () => {
this.setState({ a: this.state.a + 1 },
() => {
this.setState({ a: this.state.a + 2 },
() => {
this.setState({ a: this.state.a + 3 })
})
})
}
以上将返回 sum = 6。
什么时候不在 setState 中使用回调:
PureComponent
andshouldComponentUpdate
can be used to tune up a component’s performance. They work by preventing lifecycle methods from firing when props and state haven’t changed.The
setState
callback fires regardless of whatshouldComponentUpdate
returns. So, thesetState
callback will fire, even when state hasn’t changed.
关于javascript - 连续 setState 不能按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51104044/