我尝试在 react中做天气应用程序,但是当我在我的 const API 中添加${this.state.latitude}
时,我替换了 null。但是当我尝试在render()
中显示this.state.latitude
时,我有一个值。怎么了?
export class TodayWeather extends React.Component {
constructor(props) {
super(props);
this.state = {
latitude: "",
longitude: "",
};
}
getMyLocation =() => {
const location = navigator.geolocation;
if (location) {
location.getCurrentPosition((position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
})
},)}
};
getWeather = () => {
this.getMyLocation();
const API = `http://api.openweathermap.org/data/2.5/forecast?lat=${this.state.latitude}&lon=139&appid=${apiKey}`;
fetch(API)
.then(response => {
if (response.ok) {
return response
}
throw Error("")
})
.then(response => response.json())
.then(data => {
const time = new Date().toLocaleString();
this.setState({
})
})})
};
componentDidMount() {
this.getWeather();
}
render(){
return (
<div className="App">
<Result className="result" weather={this.state}/>
<p> {this.state.latitude} </p>
</div>
);
}
}
预期的执行顺序为:
-
this.getMyLocation()
将latitude
和longitude
设置为状态。 -
this.getWeather()
它使用状态变量发出 xhr 请求(再次异步(。
this.setState
也是异步的。因此,当设置状态变量时,this.getWeather()
已经开始执行,因此它返回 null 并且获取请求失败。因此,当设置状态变量时,它会触发重新渲染,这就是为什么它确实出现在render
中。
对此的解决方案是在setState
中使用回调。我做了一些小的修改。
我在componentDidMount
上打电话给this.getMyLocation()
:
componentDidMount() {
this.getMyLocation();
}
其中我使用回调并调用修改后的this.getWeather
:
this.setState(
{
latitude: position.coords.latitude,
longitude: position.coords.longitude
},
this.getWeather
);
它不再在开始时调用this.getMyLocation()
。
除此之外,一个明显的缺陷是,在获取完成后,您没有向setState
传递任何内容,大概是您获得的 json 数据。
.then((data) => {
const time = new Date().toLocaleString();
this.setState({
// Something needs to come here, possibly:
data
});
});
完整代码:
export default class TodayWeather extends Component {
constructor(props) {
super(props);
this.state = {
latitude: '',
longitude: ''
};
}
getMyLocation = () => {
const location = navigator.geolocation;
if (location) {
location.getCurrentPosition((position) => {
this.setState(
{
latitude: position.coords.latitude,
longitude: position.coords.longitude
},
this.getWeather
);
});
}
};
getWeather = () => {
const API = `http://api.openweathermap.org/data/2.5/forecast?lat=${
this.state.latitude
}&lon=139&appid=${apiKey}`;
fetch(API)
.then((response) => {
if (response.ok) {
return response;
}
throw Error('');
})
.then((response) => response.json())
.then((data) => {
const time = new Date().toLocaleString();
this.setState({
// Something needs to come here
data
});
});
};
componentDidMount() {
this.getMyLocation();
}
render() {
return (
<div className="App">
<Result className="result" weather={this.state} />
<p> {this.state.latitude} </p>
</div>
);
}
}
试试这个..但是代码看起来很混乱
export default class TodayWeather extends React.Component {
constructor(props) {
super(props);
this.state = {
latitude: '',
longitude: ''
};
}
getMyLocation = (getData) => {
const location = navigator.geolocation;
if (location) {
location.getCurrentPosition((position) => {
getData(position);
});
}
};
getWeather = () => {
const getData = (position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude
});
const API = `http://api.openweathermap.org/data/2.5/forecast?lat=${
position.coords.latitude
}&lon=139&appid=${apiKey}`;
fetch(API)
.then((response) => {
if (response.ok) {
return response;
}
throw Error('');
})
.then((response) => response.json())
.then((data) => {
const time = new Date().toLocaleString();
this.setState({ time });
});
};
this.getMyLocation(getData);
};
componentDidMount() {
this.getWeather();
}
render() {
return (
<div className="App">
<Result className="result" weather={this.state} />
<p> {this.state.latitude} </p>
</div>
);
}
}