我正在阅读reactjs文档的表单部分,只是尝试了这段代码来演示onChange的用法(JSBIN)。
var React= require('react');
var ControlledForm= React.createClass({
getInitialState: function() {
return {
value: "initial value"
};
},
handleChange: function(event) {
console.log(this.state.value);
this.setState({value: event.target.value});
console.log(this.state.value);
},
render: function() {
return (
<input type="text" value={this.state.value} onChange={this.handleChange}/>
);
}
});
React.render(
<ControlledForm/>,
document.getElementById('mount')
);
当我在浏览器中更新<input/>值时,handleChange回调中的第二个console.log打印与第一个console.log相同的值,为什么我看不到这个结果。setState({value: event.target.value})在handleChange回调的范围?
访问。由于setState方法的异步特性,在调用setState方法后,不能保证返回更新后的状态。
为了保证在调用setState之后进行更新,可以采用两种解决方案。
解决方案1:正如上述答案之一所提到的,将代码放在componentDidUpdate方法中
解决方案2:正如上面的另一个答案所提到的,将你的东西作为一个回调传递
this.setState({value: myValue}, function () {
this.functionThatIsExecutedWhenStateIsUpdated();
});
需要注意的是,这两种解决方案并不能明显互换。一个不能轻易地解决另一个的所有用例。作为一般规则,如果可以的话,最佳实践建议首选解决方案1。但是,在一些用例中,只有解决方案2“更有效”地工作,例如“更新我的视图和提交我的数据”用例。这个用例是这样的:
在添加一个项目后,说,“添加日程”,我想将该项目添加到前端列表,并立即将刚刚更新的列表发布到后端,如下面的概念所示:
如果你不做任何解决方案,也就是说,如果你只在你的代码中这样说:
addToItemArray = () => {
this.setState{{ scheduledItemsArray: newObjectListWithMax}}
this.postData();
}
<button className="btn btn-secondary btn-block" onClick={this.addToItemArray}>Add Shedule</button>
... 你将发布列表排除“Delivery to Max”项,因为当你this.postData()时状态不会更新(同样,因为它是异步的)。
如果您使用解决方案1,您将在输入日程名称文本框中的每个字符后进行POST !
还有其他方法来满足这个用例,但是解决方案2在阅读代码时最好地传达了意图。
考虑到这个用例在几乎每个web应用程序中无处不在的本质,Michael的回答中解释的回调技术是每个开发人员工具包中不可或缺的一段代码。