单击按钮时调用handleSelection
方法,但是,如果在到达this.setState({selectedFoods: newSelections});
时状态未设置,则单击按钮。方法中的其他所有内容都正确执行(因为我的各种console.logs告诉我:))。再次单击该按钮时,方法中的所有内容将再次执行,setState
将起作用。
var Flavor = React.createClass({
getInitialState: function() {
return { foods: {}, selectedFoods: [], affinities: [] };
},
componentDidMount: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data) {
this.setState({foods: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
componentDidUpdate: function () {
$('#select-food').selectize({
onChange: this.handleSelection
}
);
},
handleSelection: function (e) {
if (e.target) {
var selectedFood = e.target.id;
} else {
var selectedFood = e;
}
console.log(selectedFood);
if (this.state.foods[selectedFood]) {
var selections = this.state.selectedFoods;
var newSelections = selections.concat(selectedFood);
console.log("newSelections: "+newSelections)
var state = Object.assign(this.state, {selectedFoods: newSelections});
this.setState(state);
console.log("state: "+this.state.selectedFoods)
this.handleAffinities();
} else {
console.log("** "+selectedFood+" **");
}
},
handleAffinities: function() {
console.log("selectedFoods: "+this.state.selectedFoods.length)
if (this.state.selectedFoods.length > 0) {
var allAffinities = this.state.selectedFoods.map((food) => {
return this.state.foods[food];
});
console.log(allAffinities.length);
console.log(allAffinities);
var commonAffinities = allAffinities[0];
allAffinities.forEach((affinities) => {
commonAffinities = commonAffinities.filter((n) => {
return affinities.indexOf(n) != -1;
});
})
this.setState({affinities: commonAffinities});
} else {
this.setState({ affinities: [] });
}
},
handleRemove: function(food) {
var selectedFoods = this.state.selectedFoods;
var index = selectedFoods.indexOf(food);
var updatedSelection = selectedFoods.splice(index, 1);
this.setState({selectedFoods: selectedFoods});
this.handleAffinities();
},
除了setState
函数之外,为什么第一次所有内容都能正确执行?为什么它在第二次点击时起作用?
答案 0 :(得分:28)
状态正在改变它应该的方式。问题是,在调用console.log
之后,您的setState
语句会在设置新状态之前触发。
来自docs:
setState()
不会立即改变this.state
,但会创建待处理状态转换。在调用此方法后访问this.state
可能会返回现有值。
如果您想在状态转换完成后触发console.log
语句,请将函数作为回调传递给setState()
。
this.setState({selectedFoods: newSelections}, () => {
console.log(this.state.selectedFoods);
});
答案 1 :(得分:2)
正如@Micheal所述,setState函数保持待处理状态,并且第一个console.log起作用。任何想查看或尝试这种情况的人都可以看看我的codesandbox.io example。在此处,在YesNoComponentWithClass内,“是”按钮在第一次单击时记录为空,而没有按钮记录期望值。
答案 2 :(得分:0)
我也经历了一天这个问题,并找到了解决方案。 我刚刚在myCode中添加了componentDidUpdate()方法,现在一切正常。 有关生命周期的流程,请查看链接中给出的生命周期图像。