我有一个小反应应用程序。当选定的dep / arr站更改时,它将从BART API中重新获取计划数据。
由于某些原因使用旧代码(见下文),它无法正常工作。我先setState
然后尝试使用depStation
的新值,但它显示了之前的值。例如,假设我重新加载页面,初始depState值为SFIA
。如果我将值更改为FRMT
,则console.log(selected)
会显示FRMT
,但console.log(this.state.depStation)
仍显示SFIA
。如果我再次将其更改为HAYW
,则console.log(selected)
显示HAYW
,但console.log(this.state.depStation)
会显示FRMT
。为了使应用程序正常工作,我只是使用了selected
而不是this.state.depStation
,但我想这不是最佳方法。
所以我真的不明白为什么this.state.depStation
在调用this.setState({depStation: selected})
后会显示prev数据。能告诉我为什么会这样吗?
旧版本无效:
reRunFetching(selected, type) {
if (type === "depart") {
this.setState({depStation: selected});
console.log(selected); //Showing properly what I select
console.log(this.state.depStation); //For some reason the previously selected
}
else if (type === "arrive") {
this.setState({arrStation: selected});
}
this.fetchingAPI(this.state.depStation, this.state.arrStation)
}
新版本。这工作正常,但我认为这不是最好的解决方案:
reRunFetching(selected, type) {
if (type === "depart") {
this.fetchingAPI(selected, this.state.arrStation)
this.setState({depStation: selected});
console.log(selected, this.state.arrStation);
}
else if (type === "arrive") {
this.fetchingAPI(this.state.depStation, selected)
this.setState({arrStation: selected});
console.log(this.state.depStation, selected);
}
}
其余的index.js
class App extends Component {
constructor(props) {
super(props);
this.state = {
schedules: [],
depStation: DEP_STATION,
arrStation: ARR_STATION
};
this.fetchingAPI(this.state.depStation, this.state.arrStation)
}
fetchingAPI(departureStation, arrivalStation) {
fetch("http://api.bart.gov/api/sched.aspx?cmd=depart&orig=" + departureStation + "&dest=" + arrivalStation + "&date=now&key=MW9S-E7SL-26DU-VV8V&b=0&a=4&l=0")
.then(function(response) {
return response.text();})
.then((responseXML) => {
let tripsArray = this.parsingXML(responseXML);
this.setState({schedules: tripsArray});
})
.catch((error) => {
console.log(error);
});
}
render () {
return (
<div>
<div className="row">
<div className="col-md-5 col-md-offset-1 search-bar">
<SelectDepart onSelectedChange={selected => this.reRunFetching(selected, "depart")}/>
</div>
<div className="col-md-5 search-bar">
<SelectArrive onSelectedChange={selected => this.reRunFetching(selected, "arrive")}/>
</div>
</div>
<TimeTable schedules={this.state.schedules} />
</div>
)
}
答案 0 :(得分:1)
setState()是一种异步非阻塞方法,它不会像您期望的那样立即设置新状态。正如官方文档所说:
setState()不会立即改变this.state,但会创建挂起状态转换。调用此方法后访问this.state可能会返回现有值 无法保证对setState的调用进行同步操作,并且可以对调用进行批处理以获得性能提升。
如果需要,可以将回调传递给setState()的第二个参数,它将在状态更改时触发:
this.setState({depStation: selected}, function() {
// some code
});
答案 1 :(得分:0)
setState()是一个对您的状态进行排队的异步方法。所以为了在setState之后立即访问状态值,你需要调用一个回调函数作为setState方法的第二个参数,它将首先设置你的状态,之后将重新呈现你的视图更新状态。以下示例将帮助您。
<tablename>