我正在尝试为获取天气数据调用API,我需要将每个返回的数据添加到数组状态。但是它不起作用,并且仅显示最后添加的数据。有人可以解释一下为什么会发生这种情况并给我解决办法
import React, {useEffect, useState} from 'react';
import './App.css';
const data = require('../src/data/Step1'); //Importing json file
const axios = require("axios");
function App() {
//React Hook to save weather data
const [weatherData, setWeatherData] = useState([]);
//UseEffect to call getData function
useEffect(() => {
//call getData for each sending city code one by one
data.List.map(city => getData(city.CityCode));
}, []);
//getData function
async function getData(cityCode) {
//Axios get request to http get request
const response = await axios.get('http://api.openweathermap.org/data/2.5/group?id=' + cityCode + '&units=metric&appid=24e343673cb58392072a12e4705b1260');
//adding each weather object to weather data Array
setWeatherData([...weatherData,response.data.list[0]]);
}
if (weatherData.length > 1) {
return (
<div>
{
<div className="container mt-5">
{weatherData.map(x => (
<div className="row mt-2 ">
Id : {x.data.id} {" | "}
Name :{x.data.name} {" | "}
Description : {x.data.weather[0].description} {" | "}
Temperature : {x.data.main.temp}
</div>
))}
</div>
}
</div>
);
} else {
return (
<div>
<h1>Loading</h1>
</div>
)
}
}
export default App;
答案 0 :(得分:1)
setState不会同步发生,因此不能保证下次调用该状态时会更新该状态。而是尝试以下
async function getData(cityCode) {
const response = await axios.get('http://api.openweathermap.org/data/2.5/group?id=' + cityCode + '&units=metric&appid=24e343673cb58392072a12e4705b1260');
//adding each weather object to weather data Array
setWeatherData(function (currentWeatherData) {
return [...currentWeatherData, response.data.list[0]];
});
}
这是一个副本示例link
答案 1 :(得分:0)
实际上,回调weatherData是stale closure。也许以下方法会起作用:
//using useCallback so the dependency of getData to the
// effect won't cause the effect to run other than when
// the component mounts
const getData = React.useCallback(async function getData(
cityCode
) {
const response = await axios.get(
'http://api.openweathermap.org/data/2.5/group?id=' +
cityCode +
'&units=metric&appid=24e343673cb58392072a12e4705b1260'
);
setWeatherData((weatherData) => [
//using callback so weatherData is not a dependency
...weatherData,
response.data.list[0],
]);
},
[]);
useEffect(() => {
//if you don't use the result of a map then use forEach instead
data.List.forEach((city) => getData(city.CityCode));
}, [getData]);
您可以将回调传递给状态设置器setWeatherData
,以接收当前状态并返回新状态。