【问题标题】:Unable to access/manipulate data from weather API using axios with useEffect in React.js无法在 React.js 中使用带有 useEffect 的 axios 访问/操作来自天气 API 的数据
【发布时间】:2020-06-25 01:33:08
【问题描述】:

我正在使用 axios 通过 useEffect 获取天气 api 数据。

import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { Header } from './Header';

export const CurrentCity = () => {
  const [weather, setWeather] = useState({});

  console.log('weather', weather);
  console.log(weather.weather[0].icon);

  useEffect(() => {
    async function getData() {
      const url = `https://api.openweathermap.org/data/2.5/weather?q=Berlin&appid=${process.env.REACT_APP_WEATHER_KEY}`;
      try {
        const response = await axios.get(url);
        setWeather(response.data);
      } catch (err) {
        console.log(err);
      }
    }
    getData();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  return (
    <div>
      <Header api={weather} />
    </div>
  );
};

这是 console.log(data) 的结果:

{coord: {…}, weather: Array(1), base: "stations", main: {…}, visibility: 10000, …}
coord: {lon: 13.41, lat: 52.52}
weather: Array(1)
0: {id: 802, main: "Clouds", description: "scattered clouds", icon: "03n"}
length: 1
__proto__: Array(0)
base: "stations"
main: {temp: 278.43, feels_like: 270.3, temp_min: 276.48, temp_max: 280.37, pressure: 1009, …}
visibility: 10000
wind: {speed: 8.7, deg: 270, gust: 13.9}
clouds: {all: 40}
dt: 1584060559
sys: {type: 1, id: 1275, country: "DE", sunrise: 1584077086, sunset: 1584119213}
timezone: 3600
id: 2950159
name: "Berlin"
cod: 200
__proto__: Object

如果我控制台记录我得到的数据

console.log('weather', weather);

console.log(weather.weather[0].icon);

错误信息说,它无法读取[0]的属性,

或者如果我尝试更深入地了解“风”,例如,

 console.log(weather.wind.speed);

它说,无法读取速度的属性。

如果它是我想要访问的数组,我会使用 [0] 或者如果它是一个对象,我会使用点符号。

此外,我将从 axios 获得的数据传递给 Header.js

import React from 'react';

export const Header = props => {
  console.log(props.api.name);
  return (
    <div>
      <h1>{props.api.name}</h1>
    </div>
  );
};

当我尝试深入研究其他数据时,也会发生同样的情况。

我想知道我缺少什么,提前谢谢大家! 并且还想知道 1 和 2 之间有什么区别,我应该在当前情况下使用哪一个。

  1. const [weather, setWeather] = useState({});
  2. const [weather, setWeather] = useState(null);

【问题讨论】:

  • 当你调用console.log(weather.weather[0].icon);时,天气只是初始化为{},所以你会在控制台看到错误信息。
  • 1和2的区别是weather在第1个初始化为{},在第2个初始化为null

标签: javascript reactjs axios use-effect


【解决方案1】:

您的代码是正确的,但正如他们所说,weather 对象最初将设置为空对象{},因此您只需先检查它。

const App = () => {

  const [weather, setWeather] = useState(null) // change it to null for easier check

  // useEffect() ...

  if (!weather) {
    return <div>Loading indicator</div>
  }

  return (
    <div className="App">
      <Header api={weather} />
    </div>
  )
}

【讨论】:

  • 我认为问题出在console.log('weather', weather); console.log(weather.weather[0].icon); PO 正在记录一些不存在的内容。
  • 是的,我明白了,但据我了解,主要问题是他无法从Header 组件中读取数据,因此他尝试log 它。删除 log 和返回检查你会得到同样的错误。
  • @JuniusL。 here 是我的意思,如果我错了,请您出示您的解决方案吗?
  • @JongHyeokLee 谢谢。实际上 JuniusL answer' 有更好的方法,您可能希望在他发布的应用程序中使用加载指示器和错误处理。
【解决方案2】:

您收到该错误是因为您尝试访问对象中不存在的键。在以下天气中设置为空对象。

// remove this from your code
console.log('weather', weather);
// this will throw an error, since weather is an empty object.
console.log(weather.weather[0].icon);

import React, { useEffect, useState } from "react";
import axios from "axios";
import { Header } from "./Header";

export const CurrentCity = () => {
  const [weather, setWeather] = useState({});

  useEffect(() => {
    async function getData() {
      const url = `https://api.openweathermap.org/data/2.5/weather?q=Berlin&appid=${
        process.env.REACT_APP_WEATHER_KEY
      }`;
      try {
        const response = await axios.get(url);
        setWeather(response.data);
      } catch (err) {
        console.log(err);
      }
    }
    getData();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  return (
    <div>
      <Header api={weather} />
    </div>
  );
};

然后在你的标题中验证你的数据,不要假设你总是会得到正确的数据。

import React from "react";

export const Header = props => {
  console.log(props);
  return (
    <div>
      {/* here validate your data */}
      <h1>{props && props.api && props.api.name}</h1>
    </div>
  );
};

您还可以添加一个加载器来向用户显示您正在从服务器获取数据。

export const CurrentCity = () => {

  const [weather, setWeather] = useState({});
  const [isLoading, setIsLoading] = useState(true);
  const [isError, setIsError] = useState(false);

  useEffect(() => {

    async function getData() {

      const url = `https://api.openweathermap.org/data/2.5/weather?q=Berlin&appid=${
        process.env.REACT_APP_WEATHER_KEY
      }`;
      try {

        const response = await axios.get(url);
        setWeather(response.data);
        setIsLoading(false);

      } catch (err) {

        setIsError(true);
        setIsLoading(false);
        console.log(err);

      }

    }
    getData();
    // eslint-disable-next-line react-hooks/exhaustive-deps

  }, []);

  return (
    <>
      {isLoading ? (
        <h1>Loading ...</h1>
      ) : isError ? (
        <p>Something went wrong</p>
      ) : (
        <Header api={weather} />
      )}
    </>
  );

};

【讨论】:

猜你喜欢
  • 2021-09-12
  • 1970-01-01
  • 2020-08-06
  • 2015-02-08
  • 2017-01-12
  • 1970-01-01
  • 2020-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多