Javascript React use状态数组不更新

Javascript React use状态数组不更新,javascript,reactjs,axios,Javascript,Reactjs,Axios,我正在尝试调用API获取天气数据,我需要将每个返回的数据添加到数组状态。但它不起作用,只显示最后添加的数据。有人能解释一下为什么会这样,并给我一个解决方案吗 import React, {useEffect, useState} from 'react'; import './App.css'; const data = require('../src/data/Step1'); //Importing json file const axios = require("axios&

我正在尝试调用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;
import React,{useffect,useState}来自“React”;
导入“/App.css”;
const data=require('../src/data/Step1')//导入json文件
常量axios=要求(“axios”);
函数App(){
//React钩子保存天气数据
const[weatherData,setWeatherData]=useState([]);
//使用effect调用getData函数
useffect(()=>{
//逐个调用每个发送城市代码的getData
data.List.map(city=>getData(city.CityCode));
}, []);
//getData函数
异步函数getData(cityCode){
//Axios get请求到http get请求
const response=等待axios.get('http://api.openweathermap.org/data/2.5/group?id=“+cityCode+”&units=metric&appid=24e343673cb58392072a12e4705b1260”);
//将每个天气对象添加到天气数据数组
setWeatherData([…weatherData,response.data.list[0]]);
}
如果(weatherData.length>1){
返回(
{
{weatherData.map(x=>(
Id:{x.data.Id}{“|”}
名称:{x.data.Name}{“|”}
Description:{x.data.weather[0]。Description}{“|”}
温度:{x.data.main.temp}
))}
}
);
}否则{
返回(
加载
)
}
}
导出默认应用程序;

实际上,回调weatherData是一个。也许以下方法可以奏效:

//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
,该设置器接收当前状态并返回新状态。

设置状态不会同步发生,因此您不能保证下次调用时状态会更新。相反,请尝试以下方法

   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]];
          });

    }

下面是一个repl示例

您可以正确地看到setState是异步的,但使用挂钩时回调的效果是weatherData。这就是为什么linter会指出这一点,但添加它会使效果运行太多次,因此解决方案将向setWeatherData传递回调。所以你的答案是正确的,但没有正确解释为什么它不起作用。