reactjs-React setState不立即更新
我正在做一个待办事项应用程序。 这是违规代码的非常简化的版本。 我有一个复选框:
Writing Item
这是调用复选框的函数:
checkPencil(){
this.setState({
pencil:!this.state.pencil,
});
this.props.updateItem(this.state);
}
updateItem是映射为分派到redux的函数
function mapDispatchToProps(dispatch){
return bindActionCreators({ updateItem}, dispatch);
}
我的问题是,当我调用updateItem操作并在console.log状态时,它总是落后1步。 如果未选中该复选框且该复选框不为true,则仍将状态为true传递给updateItem函数。 我需要调用另一个函数来强制状态更新吗?
8个解决方案
76 votes
您应该调用第二个函数作为setState的回调,因为setState异步发生。 就像是:
this.setState({pencil:!this.state.pencil}, myFunction)
但是,在您的情况下,由于您希望使用参数来调用该函数,因此您将不得不变得更有创造力,并可能创建自己的函数来在道具中调用该函数:
myFunction = () => {
this.props.updateItem(this.state)
}
将它们结合在一起,它应该可以工作。
Ben Hare answered 2020-01-18T11:43:24Z
16 votes
由于各种原因(主要是性能),在React中调用setState是异步的。 在幕后,React会将对setState()的多次调用批处理为一个状态突变,然后一次重新渲染该组件,而不是针对每个状态更改都重新渲染。
幸运的是,解决方案非常简单-setState接受回调参数:
checkPencil(){
this.setState({
pencil:!this.state.pencil,
}, function () {
this.props.updateItem(this.state);
}.bind(this));
}
rossipedia answered 2020-01-18T11:43:49Z
10 votes
当使用当前状态的属性更新状态时,React文档建议您使用函数调用版本setState而不是对象。
所以setState而不是setState。
原因是setState更多地是要求国家进行更改,而不是立即进行更改。 React批处理那些需要提高性能的setState。
这意味着您要检查的状态属性可能不稳定。这是一个潜在的陷阱。
有关更多信息,请参见此处的文档:[https://facebook.github.io/react/docs/react-component.html#setstate]
为了回答您的问题,我会这样做。
checkPencil(){
this.setState((prevState) => {
return {
pencil: !prevState.pencil
};
}, () => {
this.props.updateItem(this.state)
});
}
GBL answered 2020-01-18T11:44:31Z
8 votes
这是因为它异步发生,所以在那个时候可能还没有更新...
根据React v.16文档,您需要使用第二种形式的setState()接受一个函数而不是一个对象:
状态更新可能是异步的
React可以将多个setState()调用批处理为单个更新 性能。
由于this.props和this.state可能会异步更新,因此您 不应依赖于它们的值来计算下一个状态。
例如,此代码可能无法更新计数器:
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
要解决此问题,请使用第二种形式的setState()来接受函数 而不是对象。 该函数将接收先前的状态 作为第一个参数,以及应用更新时的道具 作为第二个参数:
// Correct
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
Alireza answered 2020-01-18T11:45:18Z
2 votes
我同时使用了rossipedia和Ben Hare的建议,并做了以下工作:
checkPencil(){
this.setState({
pencil:!this.state.pencil,
}, this.updatingItem);
}
updatingItem(){
this.props.updateItem(this.state)
}
lost9123193 answered 2020-01-18T11:45:38Z
2 votes
Ben对于如何解决眼前的问题有很好的答案,但是我也建议您避免重复状态
如果状态处于redux中,则您的复选框应该从prop或商店中读取其自身的状态,而不是同时在其自己的组件和全局商店中跟踪检查状态
做这样的事情:
type="checkbox"
name="area" checked={this.props.isChecked}
onChange={this.props.onChange}
/>
Writing Item
一般规则是,如果您在多个地方找到需要的状态,则将其提升到一个公共父级(并非总是重做),以保持只有一个真实来源
CheapSteaks answered 2020-01-18T11:46:12Z
2 votes
尝试这个
this.setState({inputvalue: e.target.value}, function () {
console.log(this.state.inputvalue);
this.showInputError(inputs[0].name);
});
使用任何形式的showInputError函数进行验证
Anish answered 2020-01-18T11:46:36Z
2 votes
首先设定您的价值。 完成您的工作之后。
this.setState({inputvalue: e.target.value}, function () {
this._handleSubmit();
});
_handleSubmit() {
console.log(this.state.inputvalue);
//Do your action
}
Kumaresan answered 2020-01-18T11:46:56Z