无法访问React组件中的Javascript对象

时间:2018-11-19 20:59:23

标签: javascript arrays json reactjs

所以,我陷入了React的困境,这已经让我抓狂了。

我正在获取一些API数据,并试图访问任何特定的索引或进行遍历-无论我做什么,它似乎都无法正常工作!

这是主要组成部分:

class App extends React.Component {
const CityListNames = ['Peterborough', 'Manchester', 'Brighton', 'Liverpool', 'Cardiff'];

  constructor(props) {

    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      items: []
    };

  }

  // Fire our function below on app load
  componentDidMount() {
    this.getWeather();
  }

  // getWeather - make api call
  getWeather = () => {

    let results = [];

    // Loop through our cities list here to gather data 
    // We will then push this into this.state.results
    CityListNames.forEach(function (name) {

      let api_url = "http://api.openweathermap.org/data/2.5/weather?q="+name+",UK&appid="+ApiKey;
      let data;

      // get api data  
      fetch(api_url)
      .then(res => res.json())
      .then(
        (result) => {
          results.push(result); 
          console.log(result[0]);   
        },
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      );    

    });    

    this.setState({
      isLoaded: true,
      items: results
    }); 



  }  

  render() {
    const { error, isLoaded, items } = this.state;
    if (error) {
      return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      return (
        <div className="weather-app">

        </div>
      );
    }  
  }
}

export default App;

当我使用console.log(result[0]);时,它只是在控制台中输出为“ undefined”。

我试图将所有值分配给结果变量,然后将其推入状态。

当我执行console.log(items)时,它也会显示所有项目,这很奇怪。

API数据

enter image description here

任何帮助将不胜感激!

谢谢

4 个答案:

答案 0 :(得分:1)

您的意思是console.log(results [0])的'结果'的复数。在您的Promise结果中,是解析对json的响应后得到的结果。如果该响应的键名不为“ 0”(不应该为0),则您将不确定。

修改

问题不在于您正在进行异步调用,然后执行push和console.log的同步操作。问题在于您在控制台日志记录与推送正确响应之间存在错字。

fetch(api_url)
  .then(res => res.json())
  .then(
    (result) => {
      results.push(result); // <--- pushes valid response into array
      console.log(result[0]); // <--- logs undefined   
    },

响应没有键“ 0”,因此您登录时未定义,但会推送结果(有效)。因此,您将在通话结束时得到一系列正确的结果。但是您将记录一堆“未定义”来进行控制台。

答案 1 :(得分:1)

在设置状态之前,您必须等待所有api请求解决,因此不要使用forEach,而是使用map,然后返回日期承诺,如下所示:

getWeather = () => {

    // Loop through our cities list here to gather data 
    // We will then push this into this.state.results
    Promise.all(CityListNames.map(function (name) {

      let api_url = "http://api.openweathermap.org/data/2.5/weather?q="+name+",UK&appid="+ApiKey;

      return fetch(api_url)
      .then(res => res.json());

    })).then((results) => {
      this.setState({
        isLoaded: true,
        items: results
      }); 
    }).catch((error) => {
      this.setState({
        isLoaded: true,
        error
      });
    });
  }  

答案 2 :(得分:1)

尝试一下。

class App extends React.Component {
  const CityListNames = ['Peterborough', 'Manchester', 'Brighton', 'Liverpool', 'Cardiff'];
      constructor(props) {

       super(props);
        this.state = {
          error: null,
          isLoaded: false,
          items: []
        };

      }

      // Fire our function below on app load
      componentDidMount() {
        this.getWeather();
      }

      // getWeather - make api call
      getWeather = () => {

        let self = this,
            results = [], responses = [];

        // Loop through our cities list here to gather data 
        // We will then push this into this.state.results
        CityListNames.forEach(function (name) {

          let api_url = "http://api.openweathermap.org/data/2.5/weather?q="+name+",UK&appid="+ApiKey;
          let data;

          // get api data  
          fetch(api_url)
          .then(res => {
             responses.push(res.json());
           });
        };    

        Promise.all(responses).then((values) => {
          self.setState({
            isLoaded: true,
            items: results
          });
        });// this works, because setState is called after before all promises are fulfilled 
      }    

    render() {
      const { error, isLoaded, items } = this.state;
      if (error) {
        return <div>Error: {error.message}</div>;
      } else if (!isLoaded) {
        return <div>Loading...</div>;
      } else {
        return (
          <div className="weather-app">

          </div>
        );
      }  
    }
}

export default App;

答案 3 :(得分:0)

1.fetch:异步工作,因此,当您将状态值赋给状态时,它将是一个空数组。

this.setState({
        isLoaded: true,
        items: results
      });    

先前的代码必须包含在获取结果中

class App extends React.Component {
cityListNames = ['Peterborough', 'Manchester', 'Brighton', 'Liverpool', 'Cardiff']; // this is one of the changes

  constructor(props) {

    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      items: []
    };

  }

  componentDidMount() {
    this.getWeather();
  }


  getWeather = () => {

    let results = [];

    this.cityListNames.forEach(function (name) { //this is one of the changes

      let api_url = "http://api.openweathermap.org/data/2.5/weather?q="+name+",UK&appid="+ApiKey;
      let data;

      fetch(api_url)
      .then(res => res.json())
      .then((result) => {
          results.push(result); 
          this.setState({ // this is one of the changes
            isLoaded: true,
            items: results
          });    
        },
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      );    

    });    

  }  

  render() {
    const { error, isLoaded, items } = this.state;
    if (error) {
      return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      return (
        <div className="weather-app">

        </div>
      );
    }  
  }
}

export default App;