我有一個小反應的應用程序。當選定的dep/arr工作站發生變化時,它會從BART API重新獲取計劃數據。reactjs setState沒有正確更改
由於某些原因舊代碼(見下文)它不能正常工作。我先做了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>
)
}
伊利亞,你怎麼看我目前的工作版本?與你的建議相比,這是否更糟/更好? –
如果操作順序setState()和fetchingAPI()不重要(它們是獨立的),那麼你的解決方法就適合了。如果存在或可能引起一些副作用,例如競爭條件,那麼最好調用在傳遞給setState()的回調函數中獲取API()以確保執行順序。 –