Невозможно получить доступ к данным из API погоды или манипулировать ими с помощью ax ios с помощью useEffect в React. js - PullRequest
1 голос
/ 13 марта 2020

Я использую топор ios для получения данных API погоды с помощью useEffect.

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 получаю данные,

console.log('weather', weather);

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

в сообщениях об ошибках говорится, что он не может прочитать свойство [0],

или, если я попытаюсь получить более глубокий доступ к «ветру», например,

 console.log(weather.wind.speed);

говорит, что не может прочитать свойство скорости.

Если это массив, к которому я хочу иметь доступ, я бы использовал [0] или, если это объект, я бы использовал точечную нотацию.

Более того, я передаю данные, полученные из топора ios, в заголовок. js

import React from 'react';

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

То же самое происходит, когда я пытаюсь go глубже проникнуть в другой data.

Хотелось бы узнать, чего мне не хватает, Заранее всем спасибо! А также хотите узнать, в чем разница между 1 и 2, и какой из них мне следует использовать для текущей ситуации.

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

Ответы [ 2 ]

1 голос
/ 13 марта 2020

Вы получаете эту ошибку, потому что пытаетесь получить доступ к ключу, который не существует в объекте. В следующую погоду устанавливается пустой объект.

// 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} />
      )}
    </>
  );

};
1 голос
/ 13 марта 2020

Ваш код верен, но, как сказали ребята, объект 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>
  )
}

Edit romantic-bartik-9oyk3

...