首页 > 解决方案 > React - 使用`useEffect`时纬度和经度状态不正确

问题描述

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

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

鳕鱼:“400”消息:“纬度错误”

或者

鳕鱼:“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>
  );
}

标签: javascriptreactjs

解决方案


我认为您正在寻找这样的 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 函数的返回值必须是空值或清理函数。


推荐阅读