react动态改变选中不选中_reactjs-React setState不立即更新

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值