【问题标题】:Display data from API using react component and useEffect使用 react 组件和 useEffect 显示来自 API 的数据
【发布时间】:2021-02-08 10:45:25
【问题描述】:

我有这个反应组件,每次渲染时都会显示通过道具(国家)接收的国家信息,并且使用天气堆栈 API 还必须显示当前时间的首都天气。第一部分(显示来自道具的国家数据)工作正常,但我很难从天气 API 获取数据。我在控制台上看到我正在获取当前天气,但无法使用 setState() 将其分配给天气变量,因此我的应用程序崩溃了。

这是我到目前为止的组件代码,我尝试使用 async/await.then 语法,以防我拼错了一些东西,但总是得到相同的结果:

const CountryDetails = async ({country}) => {
    
    const [weather, setWeather] = useState({});

    // const hook = async () => {
    //   const result = await axios.get(`http://api.weatherstack.com/current?access_key=${WEATHER_API}&query=${country.capital}`);
    //   console.log(result.data);
    //   setWeather(result.data.current);
    //   console.log(weather);
    // }

    const hook = () => {
      axios.get(`http://api.weatherstack.com/current?access_key=${WEATHER_API}&query=${country.capital}`).then((response) => {
        console.log('then');
        setWeather({
          temperature: response.data.current.temperature,
          img: response.data.current.weather_icons,
          wind: response.data.current.wind_speed,
          dir: response.data.current.wind_direction
        });
        console.log(response.data.current);
      });
    }

    useEffect(hook, []);

    console.log(weather);

    return (
      <>
        <h1>{country.name}</h1>
        <p>capital {country.capital}</p>
        <p>population {country.population}</p>
        <h2>languages</h2>
        <ul>
          {country.languages.map((lang) => {
            <li key={lang.name}>{lang.name}</li>;
          })}
        </ul>
        <img src={country.flag}></img>
        <h2>Weather in {country.capital}</h2>
        <p><b>temperature: </b>{weather.current.temperature}</p>
        <img src={weather.current.weather_icons} />
        <p><b>wind: </b>{weather.current.wind_speed} direction {weather.current.wind_direction}</p>
      </>
    );
  };

带有完整代码的沙盒:https://codesandbox.io/s/vigilant-ride-h3t1j

【问题讨论】:

  • 为什么你的组件函数定义中有async?删除它会起作用吗?
  • 首先我使用的是 async/await 语法,现在我已经删除了,但仍然无法使用
  • 你用一个空对象初始化 weather 并尝试在你的 jsx 中访问它的属性。渲染组件时,&lt;p&gt;&lt;b&gt;temperature: &lt;/b&gt;{weather.current.temperature}&lt;/p&gt; 行将失败

标签: javascript reactjs api axios


【解决方案1】:

这是我创建的一个代码框,用于玩你的代码。既然你说你已经成功地从 API 接收数据,我用我的 getWeather 函数来模拟它。除了@Viet 回答的内容外,您提供的代码中还有其他问题。看看这是否有帮助或错误是否仍然存在,请提供复制的 sn-p 示例:

https://codesandbox.io/s/competent-dhawan-fds81?file=/src/App.js:52-62

import { useEffect, useState } from "react";

const getWeather = (country) => {
  return Promise.resolve({
    data: {
      current: {
        temperature: "<temperature>",
        weather_icons: "<weather_icons>",
        wind_speed: "<wind_speed>",
        dir: "<wind_direction>"
      }
    }
  });
};

const CountryDetails = ({ country }) => {
  const [weather, setWeather] = useState({});

  const hook = () => {
    getWeather(country).then((response) => {
      console.log("then");
      setWeather({
        temperature: response.data.current.temperature,
        img: response.data.current.weather_icons,
        wind: response.data.current.wind_speed,
        dir: response.data.current.dir,
        wind_speed: response.data.current.wind_speed
      });
      console.log(response.data.current);
    });
  };

  useEffect(hook, [country]);

  // You should get {} logged here, not undefined
  console.log(weather);

  return (
    <>
      <h1>{country.name}</h1>
      <p>Capital: {country.capital}</p>
      <p>Population: {country.population}</p>
      <h2>Languages</h2>
      <ul>
        {/* You were not returning anything in the callback of the map function */}
        {country.languages.map((lang, i) => (
          <li key={i}>{lang.name}</li>
        ))}
      </ul>
      <img src={country.flag}></img>
      <h2>Weather in {country.capital}</h2>
      <p>
        <b>temperature: </b>
        {/* As @Veit mentioned, you were accessing the wrong property */}
        {weather.temperature}
      </p>
      <img src={weather.weather_icons} />
      <p>
        <b>Wind: </b>
        {weather.wind_speed} Direction: {weather.dir}
      </p>
    </>
  );
};

export default (props) => {
  const country = {
    languages: [{ name: "<name>" }],
    flag: "<flag name>",
    capital: "<capital name>",
    name: "<Coutry Name>",
    population: "<POPULATION>"
  };
  return <CountryDetails country={country} />;
};

【讨论】:

  • 我得到了同样的结果 :(
  • 这是一个沙箱,里面有我所有的代码codesandbox.io/s/vigilant-ride-h3t1j 可能问题来自另一边
  • 请检查一下。这个沙箱是空的,除了代码沙箱的样板之外没有新的代码。
  • 现在检查 index.js 文件好像我没有保存它
  • 如果您在搜索收件箱中输入 swe 并单击 sweden 旁边的按钮,您应该会看到该国家/地区的详细信息和当前天气
【解决方案2】:

您只是从天气状态中提取错误的属性。这有效:

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

const WEATHER_API = "xxx";

const CountryDetails = ({ country }) => {
  const [weather, setWeather] = useState({});
 
  const hook = () => {
    axios
      .get(
        `http://api.weatherstack.com/current?access_key=${WEATHER_API}&query=${country.capital}`
      )
      .then((response) => {
        console.log("then", response);
        setWeather({
          temperature: response.data.current.temperature,
          img: response.data.current.weather_icons,
          wind: response.data.current.wind_speed,
          dir: response.data.current.wind_dir
        });
        console.log(JSON.stringify(weather));
      });
  };

  useEffect(hook, []);

  console.log(weather);

  return (
    <>
      <h2>languages</h2>
      <p><b>temperature: </b>{weather.temperature}</p>
      <p>
        <b>wind: </b>
        {weather.wind} direction {weather.dir}
      </p>
    </>
  );
};

export default function App() {
  return (
    <div className="App">
      <CountryDetails country={{ capital: "London" }} />
    </div>
  );
}

【讨论】:

  • 我只是像你一样尝试过,但仍然出现同样的错误,并且在它说 console.log(weather) 仍然返回 undefined 的那一行就像 setWeather 它不起作用
  • hm,那么您应该检查 API 密钥和国家/地区、大写字母。 axios.get() 的响应是什么?
  • 我用的是:
  • 我做了,它工作正常,实际上是在.console.log(reponse)里面。然后我看到结果,它是正确的
  • 是的,但如果我通过国家对象不应该同样工作?我也需要国家信息而不是首都
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-01
  • 2021-06-04
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 2018-05-20
  • 1970-01-01
相关资源
最近更新 更多