从API访问数据并输出反应

时间:2017-08-29 13:07:57

标签: javascript reactjs es6-promise

我有一个API(/js/feed/sms.json),它返回如下所示的数据:



[
    {
        id: 1,
        name: "Test feeds 1",
        headline: "Here is a headline",
        feed-url: "/something?q=1"
    },
    {
        id: 2,
        name: "Test feeds 2",
        headline: "Here is another headline",
        feed-url: "/something?q=2"
    },
    {
        id: 3,
        name: "Test feeds 3",
        headline: "Here is a third headline",
        feed-url: "/something?q=3"
    }
]




我有几个React组件。

第一个是对API的调用: 取-API-data.jsx:



import * as axios from 'axios';

export default class FetchApiData {
  constructor() {
    console.log('FetchAPIData loaded');
  }
  static shareMyStoryData(URL) {
    return axios.get(URL)
    .then(function (response) {
      
    })
    .catch(function (error) {
      console.log(error);
    });
  }
}




第二个是解析数据的组件。



import * as React from 'react';
import * as DOM from 'react-dom';
import PropTypes from 'prop-types';
import axios from 'axios';
import './share-my-story.scss';
import FetchApiData from './fetch-api-data';

class ShareMyStory extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      smsData: ''
    }
  }

  componentDidMount() {
    const URL = '/js/feed/sms.json';
    FetchApiData
      .shareMyStoryData(URL)
      .then((response) => {
        this.setState({smsData: response });
      })
      .catch((error) => {
        console.log(error);
      });
  }

  render() {
console.log(this.state.smsData);
    return (
      <div>
        <h1>{this.state.smsData.name}<h1>
        <h2>{this.state.smsData.headline}</h2>
        <h3><a href={this.state.smsData.link}>{this.state.smsData.link}</a></h3>
      </div>
    );
  }
}

ShareMyStory.propTypes = {
  name: PropTypes.string,
  headline: PropTypes.string,
  link: PropTypes.string,
  smsData: PropTypes.array
}

DOM.render(
  <ShareMyStory/>, document.getElementById('share-my-story'));
&#13;
&#13;
&#13;

我有两个问题:

首先,我在this.state.smsData的console.log中未定义。

其次,我需要循环通过该对象并在返回中输出项目。我来自Angular,所以我熟悉他们的迭代ng-repeat,但我在React中没有看到类似的工具。有没有一种首选的方法呢?

3 个答案:

答案 0 :(得分:2)

1)首先检查哪一个正在记录,当你的render()被触发时,你的fetchData可能还没有完成。这就是您获取默认smsData的原因。

2)为了循环数据,假设dataArray是你需要遍历的数组

FetchApiData
  .shareMyStoryData(URL)
  .then((response) => {
    // See if this is logging after Render is logged in
    console.log('In FetchApiData: ', this.state.smsData);
    this.setState({smsData: response });
  })

render() {
  console.log('In Render: ', this.state.smsData);

  const listItems = this.state.dataArray.map(function(item) {
    return (
      <li key="{item.name}">
        <a href="{item.link}">{item.name}</a>
      </li>
    );
  });
  return (<ul>{listItems}</ul>);
}

答案 1 :(得分:1)

如果你的FetchApiData中确实有空.then(function(response){}),那就是问题所在。要么在那里添加{return response}(无用,但至少应该有效)或删除.then

对于第二个问题,正如其他人所指出的:在React中,您使用数组的.map方法来迭代数组:

{ this.state.smsData.map(data => <div>...</div>) }

有些观点:如果你的smsData是(或将是)一个数组,那么最好用undefined或空数组初始化它。我建议undefined,所以你可以区分A)还没有数据和B.数据已被提取,但没有记录(即smsData.length === 0)< / em>的

在组件中,您可以检查是否呈现数据,加载指示符或某些没有记录的消息,如:

render() {
    const { smsData } = this.state;
    if (!smsData) { return <div>Loading...</div>; }
    if (smsData) {
        if (smsData.length === 0) { return <div>No data</div>; }
        return smsData.map(data => <div>...</div>);
    }
}

答案 2 :(得分:0)

如果你正在获取数据并且状态正在改变,但是当你在console.log中它返回undefined时可能是因为你调用console.log时没有完成setState函数。

尝试这样的事情,该函数将在setState部分完成后执行。

this.setState({
            someSate: obj
        }, () => {
            console.log(this.state.smsData);
        });