如何在React中显示对象内部的对象数组?

时间:2018-07-29 18:41:08

标签: javascript arrays reactjs object

我正在尝试制作一个模拟新闻响应应用程序,并且正在使用newsapi的node包。这将返回一个在一个对象内具有对象数组的响应。我将状态设置为newsapi函数的响应,并在将其记录到控制台时得到该对象。我只是无法在网站上显示它,因为我不知道如何显示数组中对象的状态。

这是我的App.js:

import React, { Component } from "react";
import Paper from "@material-ui/core/Paper";
import Divider from "@material-ui/core/Divider";
const NewsAPI = require("newsapi");
const newsapi = new NewsAPI("APIKEY");

class App extends Component {
  constructor() {
    super();
    this.state = { articles: {} };

    newsapi.v2
      .topHeadlines({
        category: "business",
        language: "en",
        country: "us"
      })
      .then(response => {
        this.setState({ articles: { response } });
        console.log(this.state.articles.response.articles[2]);
      });
  }

  render() {
    let article = this.state.articles;
    return (
      <div>
        <div style={{ display: "flex" }}>
          <div
            style={{ marginLeft: "23em", width: "75%", paddingBottom: "20px" }}
          >
            <Paper>
              <div style={{ textAlign: "center" }}>
                <p style={{ margin: "50px" }}>
                  <b />
                </p>
                <br />
              </div>
              <p>
                {article.map(articles => (
                  <p>{articles.name}</p>
                ))}
              </p>
              <br />
              <Divider />
            </Paper>
            <div style={{ textAlign: "center", paddingTop: "20px" }} />
          </div>
        </div>
      </div>
    );
  }
}

export default App;

我目前得到的错误是map不是函数。

来自API的响应:

enter image description here

//编辑:将文章从数组更改为对象。

//谢谢大家……devserkan的回答对我们影响最大,现在我可以继续进行我的项目了!

3 个答案:

答案 0 :(得分:1)

您正在将文章设置为对象而不是数组。 然后,当您尝试“映射”您的文章时,由于对象没有映射功能,您将收到错误消息。

您可以通过将状态下的articles对象设置为数组来解决此问题:

this.setState({ articles: response.articles }); 

请注意,我删除了响应周围的花括号,以防止创建新对象

答案 1 :(得分:1)

首先,您应该告诉您articles状态应为数组,因为它是响应中的数组。然后,您可以轻松映射它。这是一个工作示例。我在这里伪造API响应,但您可以根据自己的情况使用它。

class App extends React.Component {
  state = {
    articles: [],
  }

  response = {
    status: "ok",
    totalResults: 20,
    articles: [
      { author: "foo", title: "bar" },
      { author: "fizz", title: "buzz" },
    ]
  }

  getArticles = () =>
    new Promise( resolve =>
      setTimeout( () => resolve(this.response)), 500)

  componentDidMount() {
    this.getArticles()
      .then(response => this.setState({articles: response.articles}))
  }

  render() {
    const {articles} = this.state;
    return (
      <div>
        {
          articles.map( article => (
            <div>
            <p>Author: {article.author}</p>
            <p>Title: {article.title}</p>
            </div>
          ))
        }
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

对于您的情况,只需看一下我的示例,然后将您的articles状态设置为一个空数组。然后在componentDidMount方法中使用newsApi调用。我在这里提供您的固定代码,但是由于无法测试,因此无法确定它是否有效。

class App extends Component {
  constructor() {
    super();
    this.state = { articles: [] };
  }

  getNews = () =>
    newsapi.v2
      .topHeadlines({
        category: "business",
        language: "en",
        country: "us"
      })
      .then(response => {
        this.setState({ articles: response.articles });
      });

  componentDidMount() {
    this.getNews();
  }

  render() {
    let articles = this.state.articles;
    return (
      <div>
        <div style={{ display: "flex" }}>
          <div
            style={{ marginLeft: "23em", width: "75%", paddingBottom: "20px" }}
          >
            <Paper>
              <div style={{ textAlign: "center" }}>
                <p style={{ margin: "50px" }}>
                  <b />
                </p>
                <br />
              </div>
              <p>
                {articles.map(article => (
                  <p>{article.author}</p>
                ))}
              </p>
              <br />
              <Divider />
            </Paper>
            <div style={{ textAlign: "center", paddingTop: "20px" }} />
          </div>
        </div>
      </div>
    );
  }
}

我改变了什么?

  • 在您的状态下更改articles的形状。
  • 创建一个获取新闻的函数:getNews。
  • 在此功能中,获取新闻并像这样设置文章:this.setState({ articles: response.articles })
  • 添加componentDidMount并调用创建的函数。
  • 在渲染方法中,将article的名称更改为articles,因为这更加一致。还要在地图中将articles更改为article
  • 文章中没有name,因此我用author进行了更改。

答案 2 :(得分:-1)

地图仅适用于数组,用于in或foreach

let articles_name = [];
for (var index in  this.state.articles) {articles_name.push(<p>this.state.articles[index].name</p>)}




   {article.map(articles => <p>{articles.name}</p>)}   can be replaced by  {articles_name}