【问题标题】:React - Latitude and Longitude state incorrect when using `useEffect`React - 使用`useEffect`时纬度和经度状态不正确
【发布时间】:2021-08-11 10:44:40
【问题描述】:

我之前曾问过这个question 并实施了与链接文章相关的一些更改。但是,我仍然对如何获得我需要的东西感到困惑。我还是 React 新手,对 useEffect 没有太多经验,所以我想知道正确的做事方式。

最初的问题是我通过城市搜索数据对象的坐标来设置经纬度状态。当我 console.log 这些值时,它们看起来是正确的,但是当我在 One Call API 中使用它们时,它无法按预期工作 - 它 console.logs

cod:“400”消息:“纬度错误”

cod:“400”消息:“无需地理编码”

即使我添加了useEffect,这仍然会发生。任何帮助将不胜感激!

另一个相关问题,我使用onClick 触发了函数的API 调用,但您无法访问useEffect 中的函数。如何触发 API 调用,以便数据也呈现在页面上,就像没有 useEffect 时一样?我见过这样的例子,但在每个例子中,状态都设置为数组或对象(例如const [forecast, setForecast] = useState([]))。 lat 和 long 的状态只是数字,所以我没有将它们设置为对象或数组。这可能与最初的问题有关吗?提前致谢。

更新代码:

import { useState, useEffect } from "react";
import Weather from "./Weather";

export default function Form(props) {
  const [input, setInput] = useState("");
  const [lat, setLat] = useState();
  const [lon, setLon] = useState();
  const [forecast, setForecast] = useState([]);

  //search for weather through city name
  useEffect(() => {
    async function getWeatherData() {
      //this one has access to lat and long

      const data = await fetch(
        `https://api.openweathermap.org/data/2.5/forecast?q=${input}&cnt=7&appid=38f1fbc74deb031d79636062ba66d984`
      )
        .then((res) => res.json())
        .then((data) => {
          //set states to include weather detail, and current longitude and latitude
          setLat(data.city.coord.lat);
          setLon(data.city.coord.lon);
          const weatherInfo = [...new Set(data.list.map((item) => item))];
          setForecast(weatherInfo);
        });
 
    }
  });

  console.log("latitude -----", lat);
  console.log("longitude -----", lon);

  //search for weather with zip code
  async function getWeatherDataZip(e) {
    e.preventDefault();
    const data = await fetch(
      `  https://api.openweathermap.org/data/2.5/weather?zip=${input}&appid={APIKEY}`
    )
      .then((res) => res.json())
      .then((data) => data);

    console.log("zipzip", data);
  }

  //get precipitation info from one call API
  async function getPrecipitationData(e) {
    e.preventDefault();
    const data = await fetch(
      `  https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&exclude=hourly&appid={APIKEY}`
    )
      .then((res) => res.json())
      .then((data) => data);

    console.log("LATLON DATA", data);
  }

  //display weather details
  function displayWeather() {
    const currentTemp = [
      ...new Set(
        forecast.map((item, index) => (
          <Weather
            item={item.main}
            desc={item.weather}
            wind={item.wind}
            key={index}
          />
        ))
      ),
    ];
    return currentTemp;
  }

  function handleSubmit(e) {
    e.preventDefault();
  }

  function handleChange(e) {
    setInput(e.target.value);
  }

  return (
    <div>
      <form className="input-form" onSubmit={handleSubmit}>
        <div>
          <input
            type="text"
            className="form"
            placeholder="Enter a city name..."
            onChange={handleChange}
          />
        </div>
        <button
          type="submit"
          className="btn btn-primary"
          onClick={(e) => {
            // getWeatherData(e);
            getWeatherDataZip(e);
            getPrecipitationData(e);
          }}
        >
          Submit
        </button>
      </form>
      <div className="weather">
        <span>{displayWeather()}</span>
      </div>
    </div>
  );
}

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    我认为您正在寻找这样的 useEffect 函数:

      useEffect(() => {
        (async () => { 
          const res = await fetch(
            `https://api.openweathermap.org/data/2.5/forecast?q=${input}&cnt=7&appid=38f1fbc74deb031d79636062ba66d984`
          );
          const data = await res.json();
          //set states to include weather detail, and current longitude and latitude
          setLat(data.city.coord.lat);
          setLon(data.city.coord.lon);
          const weatherInfo = [...new Set(data.list.map((item) => item))];
          setForecast(weatherInfo);
        })();
      }, [input]);
    

    注意最后的[input]。它确保仅在输入更改时才调用 useEffect。

    当调用 useEffect 时,您当前的代码不会做任何事情,因为您所做的只是声明一个函数,而不是实际运行它。

    编辑:我们需要将异步函数包装在 useEffect 函数中,这样它就不会返回承诺:React 不喜欢这样,因为 useEffect 函数的返回值必须是空值或清理函数。

    【讨论】:

    • 感谢您的回复!我必须在此处的任何地方包含async 吗?我收到了那个部分的错误
    • 啊,是的!已编辑。
    • 我已经尝试过您的回答,发现当我尝试更深入地访问对象时,数据未定义。例如,data.city 出现在 console.log 中,但 data.city.coord 未定义。你对此有什么建议吗?谢谢!
    • 例如,如果我在应用程序中搜索 London,如果我 console.log(data.city):"city": { "id": 2643743, "name": "London", "coord": { "lat": 51.5085, "lon": -0.1257 }, "country": "GB", "population": 1000000, "timezone": 3600, "sunrise": 1628224321, "sunset": 1628278845 } 会出现,但是当我 console.log data.city.coord 时,结果未定义,因此我无法访问其中的任何内容
    • 对不起,这真的没有意义。你在某个地方犯了错误。如果这就是 data.city 显示的内容,那么 data.city.coord not 未定义。请仔细检查您在做什么。
    【解决方案2】:

    尝试将您的 useEffect 替换为类似的内容。

      useEffect(() => {
        (async() => {
          await fetch(
              `https://api.openweathermap.org/data/2.5/forecast?q=${input}&cnt=7&appid=38f1fbc74deb031d79636062ba66d984`
            )
              .then((res) => res.json())
              .then((data) => {
                //set states to include weather detail, and current longitude and latitude
                setLat(data.city.coord.lat);
                setLon(data.city.coord.lon);
                const weatherInfo = [...new Set(data.list.map((item) => item))];
                setForecast(weatherInfo);
              });
        })()
      }, [input]);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多