Weather App using react always return null

Weather App using react always return null

我正在尝试使用 React 和 OpenWeathermap API 创建一个 WeatherApp 作为初学者项目。从 API 获取数据后,我无法 return 任何组件,因为它总是从条件语句中 returns null。

import React, {useEffect, useState } from "react";


 export default function App(){

 const API_KEY = somekey; 

 const [lat, setLat] = useState([]);
 const [long, setLong] = useState([]);
 const [data, setData] = useState([]);

 useEffect(() => {
   const fetchData = async () => {

     navigator.geolocation.getCurrentPosition(function (position) {
       console.log(position.coords.latitude);
       setLat([position.coords.latitude]); //sets latitude
       setLong([position.coords.longitude]); //sets longitude
     });
     await fetch(
       `https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${long}&exclude=hourly,minutely&units=metric&appid=${API_KEY}`
     )
       .then((res) => res.json())
       .then((result) => {
         setData([result]);
         console.log(data);
       });
   };
   fetchData();
 }, [lat, long]);

  return (
    <div className="App">
      {(typeof data.main !== 'undefined') ? (
        <h1>{data.name}</h1>  //doesnt execute
      ) :null}
    </div>
  );
}

项目基于此示例:https://www.freecodecamp.org/news/learn-react-by-building-a-weather-app/

因为 navigator.geolocation.getCurrentPosition 是异步的,所以在调用 setLat 等之前调用 fetch

注意:我对 reactjs 的了解有限,所以您可能无法在 useEffect 中执行以下操作 - 如果是这样,请提前致歉

fetchData 中,您将在 navigator.geolocation.getCurrentPosition 的回调中从 openweathermap 获取数据 - 就像这样

const fetchData = () => {
    navigator.geolocation.getCurrentPosition(position => {
        setLat([position.coords.latitude]); //sets latitude
        setLong([position.coords.longitude]); //sets longitude
        fetch(`https://api.openweathermap.org/data/2.5/onecall?lat=${position.coords.latitude}&lon=${position.coords.longitude}&exclude=hourly,minutely&units=metric&appid=${API_KEY}`)
        .then(res => res.json())
        .then(result => {
            setData([result]);
        });
    });
};

注意,不使用任何 async 因为没有使用 await

如果你想使用异步等待,你可以像这样“承诺”navigator.geolocation.getCurrentPosition

const getCurrentPosition = options => new Promise((resolve, reject) => navigator.geolocation.getCurrentPosition(resolve, reject, options));

那你就可以这样使用了

const fetchData = async () => {
    const position = await getCurrentPosition(); // the promisified function above
    setLat([position.coords.latitude]); //sets latitude
    setLong([position.coords.longitude]); //sets longitude

    const res = await fetch(`https://api.openweathermap.org/data/2.5/onecall?lat=${position.coords.latitude}&lon=${position.coords.longitude}&exclude=hourly,minutely&units=metric&appid=${API_KEY}`);
    const result = await res.json();
    
    setData([result]);
};

另请注意,在这两种情况下,代码在调用 openweathermap 时使用 position.coords.latitudeposition.coords.longitude 而不是 latlong - 由于我缺乏关于 reactjs 的知识,我不知道 setLat 是否会“同步”更改 lat(同样,我的 reactjs 知识非常有限)