Javascript 无法在React.js中使用带有useEffect的axios从天气API访问/操作数据

Javascript 无法在React.js中使用带有useEffect的axios从天气API访问/操作数据,javascript,reactjs,axios,use-effect,Javascript,Reactjs,Axios,Use Effect,我正在使用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('wea

我正在使用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记录我获得的数据

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>
  );
};
从“React”导入React;
export const Header=props=>{
console.log(props.api.name);
返回(
{props.api.name}
);
};
当我试图深入研究其他数据时,也会发生同样的事情

我想找出我错过了什么,提前谢谢大家! 还想知道1和2之间的区别是什么,在当前情况下我应该使用哪一个

  • const[weather,setWeather]=useState({})
  • const[weather,setWeather]=useState(null)

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

    const-App=()=>{
    const[weather,setWeather]=useState(null)//将其更改为null以便于检查
    //useEffect()。。。
    如果(!天气){
    返回装载指示器
    }
    返回(
    )
    }
    

    您遇到该错误是因为您试图访问对象中不存在的密钥。在以下天气条件下,设置为空对象

    // 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>
      );
    };
    
    //将其从代码中删除
    控制台日志(“天气”,天气);
    //这将抛出一个错误,因为天气是一个空对象。
    console.log(weather.weather[0].图标);
    从“React”导入React,{useffect,useState};
    从“axios”导入axios;
    从“/Header”导入{Header};
    导出常数CurrentCity=()=>{
    const[weather,setWeather]=useState({});
    useffect(()=>{
    异步函数getData(){
    常量url=`https://api.openweathermap.org/data/2.5/weather?q=Berlin&appid=${
    process.env.REACT\u APP\u WEATHER\u键
    }`;
    试一试{
    const response=wait axios.get(url);
    setWeather(response.data);
    }捕捉(错误){
    控制台日志(err);
    }
    }
    getData();
    //eslint禁用下一行react HOOK/deps
    }, []);
    返回(
    );
    };
    
    然后在你的标题中验证你的数据,不要假设你总能得到正确的数据

    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>
      );
    };
    
    从“React”导入React;
    export const Header=props=>{
    控制台日志(道具);
    返回(
    {/*此处验证您的数据*/}
    {props&&props.api&&props.api.name}
    );
    };
    
    您还可以添加一个加载器,向用户显示您正在从服务器获取数据

    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} />
          )}
        </>
      );
    
    };
    
    export const CurrentCity=()=>{
    const[weather,setWeather]=useState({});
    const[isLoading,setIsLoading]=useState(true);
    const[isError,setIsError]=useState(false);
    useffect(()=>{
    异步函数getData(){
    常量url=`https://api.openweathermap.org/data/2.5/weather?q=Berlin&appid=${
    process.env.REACT\u APP\u WEATHER\u键
    }`;
    试一试{
    const response=wait axios.get(url);
    setWeather(response.data);
    设置加载(假);
    }捕捉(错误){
    setIsError(真);
    设置加载(假);
    控制台日志(err);
    }
    }
    getData();
    //eslint禁用下一行react HOOK/deps
    }, []);
    返回(
    {孤岛加载(
    加载。。。
    ):伊瑟罗(
    出了点问题

    ) : ( )} ); };
    当您调用
    控制台.log(weather.weather[0].图标)时,天气只是初始化为
    {}
    ,因此您可以在控制台中看到错误消息。1和2中的区别在于
    weather
    在第一个中初始化为
    {}
    ,在第二个中初始化为
    null
    2nd@JongHyeokLee我认为问题出在这里
    console.log('weather',weather);console.log(weather.weather[0].图标)
    PO正在记录一些不存在的内容。请看是的,我看到了,但从我了解的主要问题来看,他无法从
    Header
    组件读取数据,因此他尝试
    log
    它。删除
    日志和返回检查,您将得到相同的错误。@JuniusL。这就是我的意思,如果我错了,你能给出你的解决方案吗?@JongHyeokLee谢谢。事实上,JuniusL answer有更好的方法,你可能想在你的应用程序中使用加载指示器和错误处理,正如他所发布的。谢谢你的帮助!我非常感激!我的代码工作了@JongHyeokLee请看
    
    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} />
          )}
        </>
      );
    
    };