react useState setState 在第一次加载时未定义,但在刷新后完美运行

react useState setState is undefined on firstload but works perfectly after refresh

我正在学习 React 并制作天气应用程序。它从开放天气中获取 API 并将响应分配给数据,然后使用 setCity 将值设置为城市。但是在第一次加载时,城市变量是未定义的,当我控制台注销数据时,它具有所有 JSON 对象。

const [city, setCity] = useState({})
  
  useEffect(()=>{
    getWeather()
  },[setCity])

  const getWeather = async ()=> {
    const reqAPI = `http://api.openweathermap.org/data/2.5/weather?q=toronto&units=metric&appid=${API_KEY}`

    const response = (await fetch(reqAPI)).json()
    const data = await response
    console.log(data)
    setCity(data)
    console.log(city)
  }

控制台日志数据可以提供所有值,但城市在首次加载时未定义并导致应用程序崩溃。请帮忙,因为我找不到解决方案

Here is the console output both should be same but are not!

You can see after editing out the code I am still getting this error

line 20 and 23 console output

City 在第一次加载时是一个空对象,这正是应该发生的情况。不要修复它,而是.. 处理这个状态。

首先,状态最好用undefined初始化:

const [city, setCity] = useState()

然后稍后在组件中处理这种情况:

return <div>Loading...</div>;

您应该将 getWeather 函数移动到 useEffect 挂钩内。此外,反应状态更新是异步的,因此当您在 setCity 之后尝试 console.log(city.main) 时,无法保证状态已更新。如果你想在状态更新时 console.log 那么你可以在依赖数组中使用另一个带有 city 的 useEffect。

Fetch 给出 promise 作为输出,需要用 .then() 处理,即 then() 部分在 promise 完成后执行。还将您的州城市添加到依赖项数组,如下所述。

像这样更新你的 useEffect

useEffect(() => {
    const reqAPI = `http://api.openweathermap.org/data/2.5/weather?q=toronto&units=metric&appid=${API_KEY}`;
    fetch(reqAPI)
        .then((response) => {
            console.log(response);
            response = response.json();
            console.log(response);
            setCity(response);
        })
        .catch((e) => console.log(e));
}, [city]);

并删除 getWeather 函数。

看看承诺 here


更新: 仅当城市不是像这样的空对象时才渲染您的城市组件

{Object.keys(city).length !== 0 ? <YourCityComponent/> : <div></div>}

在这里,我添加了一个检查以在城市为 {} 时不呈现,并且在上面的声明中 <YourCityComponent/> 指的是您的 <City key={city.id} name={city.name} etc./>.

可以通过多种方式完成,但这是最容易理解的。 也看看这个如何 check if your object is empty.