我正在尝试制作一个模拟新闻响应应用程序,并且正在使用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的响应:
//编辑:将文章从数组更改为对象。
//谢谢大家……devserkan的回答对我们影响最大,现在我可以继续进行我的项目了!
答案 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
的形状。this.setState({ articles: response.articles })
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}