【问题标题】:React, Get Weather Aync Await Errors反应,获取天气异步等待错误
【发布时间】:2021-08-19 01:41:35
【问题描述】:

我还在自学 React,并且在我遇到问题时正在做一个项目。

我有以下代码。

    const Weather = (props) => {
    const [weather, setWeather] = useState([]);
    const [lat, setLat] = useState([]);
    const [long, setLong] = useState([]);

    useEffect(() => {
      const fetchData = async () => {
        navigator.geolocation.getCurrentPosition(function (position) {
          setLat(position.coords.latitude);
          setLong(position.coords.longitude);
        });

      await fetch(`https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${long}&appid=SomeID&units=imperial&exclude=minutely`
      )
        .then((res) => res.json())
        .then((result) => {
          setWeather(result);
          console.log(result);
        });
    };
    fetchData();
    }, [lat, long]);

   return (
    <React.Fragment>
      <div className={styles.weather}>
        <div className={styles.weather__current}>{weather.current.temp}</div>

        <div className={styles.weather__hourly}>Hourly</div>
        <div className={styles.weather__daily}>5 Day</div>
      </div>
    </React.Fragment>
  );
};

export default Weather;

我的问题是我的请求在“填充”经纬度之前发出了两次,在第三次尝试时它就很好了。所以我收到了 2 个错误请求的响应,第三个是我想要的。

我的理解是,在异步函数中,等待将“暂停”,直到所有先前的变量都“满足”。我可能误解了。

我可以“硬编码”这些值,一切都很好。

任何帮助将不胜感激。

【问题讨论】:

  • await 关键字将在 fetch Promise 被解析时等待。如果navigator.geolocation.getCurrentPosition 是一个承诺,您可以在它之前使用await。但它看起来不像一个承诺,我认为你可以将你的 fetch 移动到 getCurrentPosition 的回调中,你可以在其中设置状态并发送你的 fetch 请求。我认为您不再需要经纬度状态

标签: reactjs async-await


【解决方案1】:

问题是您在 useEffect 函数本身内设置了两个 useEffect 的依赖项(lat 和 long)。您需要将您的 useEffect 分成两个独立的:第一个获取 lat 和 long,第二个获取天气。

useEffect(() => {
    navigator.geolocation.getCurrentPosition(function (position) {
      setLat(position.coords.latitude);
      setLong(position.coords.longitude);
    });
  }, []);

useEffect(() => {  
    fetch(`https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${long}&appid=SomeID&units=imperial&exclude=minutely`)
      .then((res) => res.json())
      .then((result) => {
      setWeather(result);
      console.log(result);
    });
  }, [lat, long]);

或者,由于您没有渲染纬度和经度,您可以将它们设为普通变量,而不是状态变量:

useEffect(() => {
    navigator.geolocation.getCurrentPosition(function (position) {
      const lat = position.coords.latitude);
      const long = position.coords.longitude);
      fetch(`https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${long}&appid=SomeID&units=imperial&exclude=minutely`)
        .then((res) => res.json())
        .then((result) => {
        setWeather(result);
        console.log(result);
      });
    });
  }, []);

【讨论】:

  • 第三种选择是将navigator.geolocation.getCurrentPosition转换为promise并使用async await方式
  • 谢谢,我越想越明白这和状态“刷新”有关
【解决方案2】:

您的请求执行了两次,因为您在设置天气之前设置了纬度和经度状态,并且您知道每次设置/更改组件中的状态时,react 都会再次更新它。

解决方案是使用 useRef 钩子而不是 useState 来表示 lat 和 long。如果不在其他任何地方使用这些值,您也可以使用 const 变量临时存储。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-21
    • 1970-01-01
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 2021-01-30
    相关资源
    最近更新 更多