React setState 在第一次尝试时不起作用,但在第二次尝试时起作用?
Posted
技术标签:
【中文标题】React setState 在第一次尝试时不起作用,但在第二次尝试时起作用?【英文标题】:React setState not working on first try, but works on second? 【发布时间】:2016-10-17 06:04:11 【问题描述】:我在单击按钮时调用了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
函数之外的所有东西第一次都能正确执行?为什么它在第二次点击时起作用?
【问题讨论】:
您的if (this.state.foods[selectedFood])
是否因某种原因无效?也许this.state.foods
第一次还是空的还是类似的?
您的getInitialState
函数中有什么?你可以发布整个组件,也许在 JSFiddle 中?
谢谢,我把所有东西都加到了 render 方法中
我可以通过替换它来让它工作:var state = Object.assign(this.state, selectedFoods: newSelections); this.setState(state);
这能回答你的问题吗? setState doesn't update the state immediately
【参考方案1】:
状态正在按照应有的方式发生变化。问题是,在您调用 setState
之后,您的 console.log
语句会在新状态设置之前触发。
来自docs:
setState()
不会立即改变this.state
,而是创建一个挂起的状态转换。调用此方法后访问this.state
可能会返回现有值。
如果您想在状态转换完成后触发console.log
语句,请将函数作为回调传递给setState()
。
this.setState(selectedFoods: newSelections, () =>
console.log(this.state.selectedFoods);
);
【讨论】:
这真是太好了。我的组件状态也没有得到更新,因为 DOM 没有按预期改变。 请注意:我正在为一个切换函数而苦苦挣扎,我需要这样的东西:“在 this.setState 之后我需要一个函数来触发。我通过在正如@Michael 所说,setState 回调,效果非常好。 谢谢!我有一段时间试图弄清楚这一点。现在我所有的 setState 都使用了回调,我没有任何问题。 优秀的答案。它帮助了我的代码;现在我可以在 setState 设置后立即提出请求。 :) 非常感谢。【参考方案2】:我也被这个问题困扰了一天,得到了解决方案。 我刚刚在 myCode 中添加了 componentDidUpdate() 方法,现在一切正常。 有关生命周期的流程,请查看链接中给出的生命周期图像。
【讨论】:
【参考方案3】:正如@Micheal 所说,setState 函数保持挂起状态,并且第一个 console.log 有效。任何想看到或尝试这种情况的人都可以看看我的codesandbox.io example。在这里,在 YesNoComponentWithClass 中,第一次单击时 yes 按钮记录为空,而 no 按钮记录预期值。
【讨论】:
以上是关于React setState 在第一次尝试时不起作用,但在第二次尝试时起作用?的主要内容,如果未能解决你的问题,请参考以下文章
ES6/React:为啥我的三重嵌套 setState 更新不起作用?
TypeError:未定义不是对象(评估'this.setState')[重复]