【问题标题】:Accessing data from API and outputting in react从 API 访问数据并在反应中输出
【发布时间】:2017-08-29 13:07:56
【问题描述】:

我有一个 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 的调用: fetch-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'));

我有两个问题:

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

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

【问题讨论】:

  • 执行get后有没有数据?
  • 如果我在fetchDataApi 类中登录shareMyStoryData 方法,我会看到来自get 的数据。在 ShareMyStory.jsx 组件的 return 中的 console.log 语句中,我得到undefined

标签: javascript reactjs es6-promise


【解决方案1】:

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

【讨论】:

  • this.setState(...) 应该调用 forceUpdate() 来重新渲染组件。 state.smsData 不应该用正确的数据填充吗?
  • 登录这两个区域会产生undefined,但如果我将响应记录在fetch-data-api.tsx 文件中(在.then 函数中),我会得到数据。
  • 修复了数据不返回的问题,但是当我尝试实现返回的 .map 时,我得到了这个错误:TypeError: smsData.map is not a function 我在 render() 中设置了 smsData: const { smsData } = this.state; 如上 0Rxm 的回答所示。
  • smsData 是一个数组吗? map() 是数组的默认原型函数
  • smsData 是一个对象数组。请参阅问题顶部的结构。
【解决方案2】:

如果您的 FetchApiData 中确实有那个空的 .then(function(response){}),那么这就是问题所在。要么在那里添加 { return response }(没用,但至少它应该可以工作)要么删除 .then

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

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

一些要点:如果您的 smsData 是(或将是)一个数组,那么最好使用 undefined 或空数组对其进行初始化。我建议undefined,这样你就可以区分A)还没有数据,和B。数据已被提取,但没有记录(即smsData.length === 0

然后,您可以在您的组件中检查是否呈现数据、加载指示器或一些没有记录的消息,例如:

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

【讨论】:

  • 看来问题有两个方面:1)在FetchApiData 方法中有.then 确实是原因。将其移动到组件中使用该方法的位置解决了它。还有 JSON 格式不正确的情况(缺少键名周围的双引号)。解决这两个问题解决了这个问题。感谢大家的帮助!
  • 很高兴你解决了它。顺便说一句,如果你没有真正调用外部 API,而是从本地文件中读取,你根本不需要 axios :)
  • 谢谢,很高兴知道。在这种情况下,出于开发目的,提要位于本地文件中,但一旦提要准备就绪,它将成为外部 API URL。
  • 我想的也差不多。祝你好运!
【解决方案3】:

如果您正在获取数据并且状态正在发生变化,但是当您使用 console.log 时它返回 undefined,这可能是因为 setState 函数在您调用 console.log 时尚未完成。

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

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

【讨论】:

    猜你喜欢
    • 2021-07-30
    • 2018-08-20
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 2019-12-12
    • 1970-01-01
    相关资源
    最近更新 更多