我刚刚启动了一个简单的天气应用项目来训练React和数据获取。
import React, { Component } from 'react';
import './App.css';
import axios from 'axios';
class App extends Component {
constructor(props) {
super(props);
this.state = {
city: "",
id: 0
}
this.choseCity = this.choseCity.bind(this);
this.cityName = this.cityName.bind(this);
this.cityInfo = this.cityInfo.bind(this);
}
chooseCity(e) {
console.log(e.target.value)
this.setState({
city: e.target.value
});
}
cityName() {
axios.get(`https://www.metaweather.com/api/location/search/?query=${this.state.city}`)
.then(res => res.data)
.then(data => this.setState({
city: data[0].title,
id: data[0].woeid}))
}
cityInfo() {
axios.get(`https://www.metaweather.com/api/location/${this.state.id}/`)
.then(res => console.log(res.data))
}
render() {
return (
<div className="App">
<input type="text" placeholder="Enter city name" value={this.state.city} onChange={this.chooseCity}/>
<button onClick={this.cityName}>Name</button>
<button onClick={this.cityInfo}>Info</button>
</div>
);
}
}
export default App;
所以,我有2个函数(cityName和cityInfo),我能够在2个不同的onClick事件上执行。他们似乎都独立工作。
cityName()请求存储在我所在州的数据。
cityInfo()在请求的url中使用此状态以获取更多信息。
我试图将它们链接起来以便能够在一次调用中检索所有数据,但由于它们都是异步的,我的第二个请求在第一个请求存储在我的状态之前开始,并且在api中没有办法我可以在一个请求中直接获取我需要的信息。
我尝试了一些事情,例如将它们分组到一个函数中,但到目前为止还没有结论。
解决方案:来自@elsyr
这是如何在一个函数中链接,使用请求之间的数据:
cityInfo() {
axios.get(`https://www.metaweather.com/api/location/search/?query=${this.state.city}`)
.then(res => res.data)
.then(data => {
axios.get('https://www.metaweather.com/api/location/' + data[0].woeid)
.then(res => res.data)
.then (data => this.setState({
info: data
}))
});
}
答案 0 :(得分:1)
据我所知,您希望在cityInfo
中设置状态后立即触发cityName
中的呼叫。
这是完全可能的 - setState
是异步的(因为你似乎已经想到了),但是setState也有一个可以使用的可选callback parameter。回复保证在修改状态后触发。
您的代码在cityName
中可能看起来像这样:
cityName() {
axios.get(`https://www.metaweather.com/api/location/search/?query=${this.state.city}`)
.then(res => res.data)
.then(data => this.setState({
city: data[0].title,
id: data[0].woeid}),
this.cityInfo); // callback here! runs after the state is set!
}
您拥有的另一个选项就是将您的axios
电话联系在一起。如果我们在这里查看你的代码块:
cityName() {
axios.get(`https://www.metaweather.com/api/location/search/?query=${this.state.city}`)
.then(res => res.data)
.then(data => {
// data here already contains the id - data[0].woeid
// we can just use it here to kick off another request - something like:
// axios.get('https://www.metaweather.com/api/location/' + data[0].woeid)
});
}
由于您使用了.then()
,因此您知道在开始cityInfo
通话之前,您可以保证拥有自己的数据。这可能需要更多的重构,但如果你只是保持cityName
的状态在cityInfo
中使用它,那么这可能是个更好的主意。