我对setState()接受的object.The代码链接感到困惑,这里是https://codepen.io/DRL9/pen/jadbWq,代码如下:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
intervalCount: 1,
buttonCount: 1
};
this.increment = 1;
this.intervalId = null;
}
tick() {
this.setState({
intervalCount: this.state.intervalCount + this.increment
});
this.setState({
intervalCount: this.state.intervalCount + this.increment
});
}
onClick() {
this.setState({
buttonCount: this.state.buttonCount + this.increment
});
this.setState({
buttonCount: this.state.buttonCount + this.increment
});
}
componentDidMount() {
this.intervalId = setInterval(() => this.tick(), 1000);
}
componentWillUnmount() {
clearInterval(this.intervalId);
}
render() {
return <div>
<div>
interval counter: {this.state.intervalCount}
</div>
<button onClick={this.onClick.bind(this)}>increment</button>
<div>
button counter: {this.state.buttonCount}
</div>
</div>;
}
}我希望当我单击按钮时,1会像行为一样增加。然而,它增加了2每个滴答。唯一不同的是,一个更新是在setInterval函数中,另一个更新是在onClick函数中。
为什么他们的行为不同?
发布于 2017-12-02 04:54:58
我们不能以绝对的方式谈论setState的时间,从定义上来说,它就是setState状态更改可能会延迟到将来的某个时间,根据您正在使用的React版本,这种行为可能会有所不同。
在提供的示例中,React将状态更新推迟到onClick处理程序运行完毕。React知道这个处理程序什么时候完成运行,因为我们通过JSX的onClick传递处理程序(然后由are在内部处理):
// React processes the onClick handler below
<button id="btn" onClick={this.onClick.bind(this)}>increment</button> 如果我们自己来测试onClick逻辑,通过从DOM中手动抓取button元素并添加一个调用onClick处理程序的单击事件侦听器,button将相同地更新到setInterval (React不知道我们在单击处理程序中更新状态,因此它选择不优化对setState的批处理)。
请参见此码页,其中按钮计数器在componentDidMount函数中手动添加了一个单击处理程序,而不是使用JSX的onClick。注意,按钮计数器现在以间隔2而不是1递增。
我想强调的是,这种行为是,而不是确定性的,您不应该在setState函数中使用this.state。相反,您希望使用setState的变体,它接受包含前一个状态的更新器函数。然后,从传递给更新程序的状态构建新状态:
this.setState(state => ({
buttonCount: state.buttonCount + this.increment
}));请参阅此码页,它使用更新程序更新按钮计数器,产生按2间隔更新按钮计数器的预期效果。
有关setState的更多信息,请参见正式文件。
发布于 2017-12-02 04:19:49
来自setState文档:
把setState()看作是一个请求,而不是更新组件的直接命令。为了更好地感知性能,React可能会延迟它,然后一次更新几个组件。React不能保证立即应用状态更改。
这意味着,当您在使用this.state.buttonCount更改状态数据(如第二个setState命令中的两个函数)之后立即引用状态数据( setState或this.state.intervalCount)时,行为将是不可预测的。也许setState会立即更新状态数据,就像它在intervalCount中所做的那样,也许setState会等待更新状态数据,以便以后对其进行批处理,就像对buttonCount一样。作为开发人员,当我们希望在同一事件中多次修改状态时,我们应该避免暴露于这种不可预测的行为。
至于为什么intervalCount一直被立即更新(因此是第二次更新)和buttonCount一直被批处理(对setState的两个调用只增加一次),我的猜测是:onClick是由用户交互触发的,因此响应引擎可能猜测,在用户交互期间,许多状态可能会发生变化,因此它会对对setState的调用进行批处理,直到事件完全传播为止。另一方面,tick是由内部回调触发的,而不需要处理任何用户交互,因此,React引擎可能猜测无需批处理就立即更新状态是安全的。
https://stackoverflow.com/questions/47604398
复制相似问题