首页 > 解决方案 > 在小型天气应用程序中使用 axios.get () 而不是 fetch() 时,我遇到了状态从未更新且应用程序未重新渲染的问题

问题描述

我正在开发一个使用 react 作为实践的小型天气应用程序,我的目标是更好地使用 Axios,因为它是我正在实习的公司所需的 HTTP 客户端,但我遇到了问题。我来给你展示:

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

const Api = {
  apiKey: "",
  baseURL: "https://api.openweathermap.org/data/2.5/",
};

function App() {
  const [query, setQuery] = useState("");
  const [weather, setWeather] = useState({});

  function Search(e) {
    if (e.key === "Enter") {
      fetch(
        `${Api.baseURL}/weather?q=${query}&units=metric&appid=${Api.apiKey}`
      )
        .then((res) => res.json())
        .then((result) => {
          setWeather(result);
          setQuery("");
        });
    }
  }
  
  // function Search(e) {
  //   if (e.key === "Enter") {
  //     axios
  //       .get(
  //         `${Api.baseURL}/weather?q=${query}&units=metric&appid=${Api.apiKey}`
  //       )
  //       .then((result) => {
  //         setWeather(result);
  //         setQuery("");
  //       })
  //       .catch((error) => console.log(error));
  //   }
  // }


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

  function dateBuilder(d) {
    let months = [
      "January",
      "February",
      "March",
      "April",
      "May",
      "June",
      "July",
      "August",
      "September",
      "October",
      "November",
      "December",
    ];
    let days = [
      "Sunday",
      "Monday",
      "Tuesday",
      "Wednesday",
      "Thursday",
      "Friday",
      "Saturday",
    ];
    let day = days[d.getDay()];
    let date = d.getDate();
    let month = months[d.getMonth()];
    let year = d.getFullYear();

    return `${day} ${date} ${month} ${year}`;
  }
  return (
    <div
      className={
        typeof weather.main != "undefined"
          ? weather.main.temp > 16
            ? "container warm"
            : "container"
          : "container"
      }
    >
      <div className="search-area">
        <input
          type="text"
          className="search-bar"
          placeholder="Search by city name (Ex: Paris)"
          onChange={handleChange}
          onKeyPress={Search}
          value={query}
        />
      </div>
      {typeof weather.main != "undefined" ? (
        <div>
          <div className="location-box">
            <div className="location">
              {weather.name},{weather.sys.country}
            </div>
            <div className="date"> {dateBuilder(new Date())}</div>
          </div>

          <div className="weather-box">
            <div className="temp">{Math.round(weather.main.temp)}°C</div>
            <div className="weather">{weather.weather[0].main}</div>
          </div>
        </div>
      ) : (
        ""
      )}
    </div>
  );
}

export default App;

如您所见,我使用 fetch() 解决了问题(我在网上查了一下,有人使用 fetch 做了一个类似的应用程序,所以我尝试了它并且它有效,但我不知道它为什么真的有效),正如您在渲染零件之前所看到的我的应用程序使用三元运算符检查是否(weather.main!= undefined),因此我确保返回 api 调用并强制 setWeather 对重新渲染和更新状态做出反应。但是当使用 axios.get 的注释搜索功能时,api 调用是成功的,我可以在我的控制台中看到它,但是 weather.main 总是被解析为未定义,我觉得应用程序没有重新渲染,我在网上查了一下,每个人都说该应用程序没有更新状态并重新渲染,但我不知道如何修复它。任何帮助将不胜感激,谢谢你,和平。

标签: javascriptreactjsapiwebaxios

解决方案


axios将异步调用的结果包装在对象中。您可以访问数据对象内的结果。

axios.get(url)
   .then(res => res.data)

推荐阅读