繁体   English   中英

如何将“结果”对象嵌套在数组“新闻”中并映射到它?

[英]How do I get the “results” object nested in the array “news” and map over it?

我正在尝试映射使用componentDidMount获取的数组。 但是,我一直收到同样的错误“Uncaught TypeError:this.state.news.map不是函数”。

这是在componentDidMount上

componentDidMount() {
        fetch(
            "https://content.guardianapis.com/search?api-key=test"
        )
            .then(response => response.json())
            .then(data => {
                this.setState({
                    news: data
                })
                console.log(data)
            })
    }

这是我映射数据的功能

renderNews() {
        return this.state.news.map((a, i) => (
            <div key={i}>
                {a.response.map((b, i) => (
                    <div key={i}>
                        <div key={i} className="newsEach">
                            <h3>{b.webTitle}</h3>
                            <ul className="newsInfoUl">
                                <li className="newsInfoEach">{b.type}</li>
                                <li className="newsInfoEach">
                                    {b.sectionName}
                                </li>
                                <li className="newsInfoEach">{b.pillarName}</li>
                                <li className="newsInfoEach">{b.webUrl}</li>
                            </ul>
                        </div>
                    </div>
                ))}
            </div>
        ))
    }

然后我在这里渲染出数据

render() {
        return (
            <div className="newsWrapper">
                {/* <h3>{this.renderNews()}</h3> */}
                <h3>Hello</h3>
            </div>
        )
    }

更新#1以下是我从console.log获取的数据(数据)

{response: {…}}
response:
currentPage: 1
orderBy: "newest"
pageSize: 10
pages: 211707
results: Array(10)
0: {id: "business/live/2019/may/31/markets-trump-shock-mexi…ffs-trade-war-china-brexit-ftse-100-business-live", type: "liveblog", sectionId: "business", sectionName: "Business", webPublicationDate: "2019-05-31T08:25:12Z", …}
1: {id: "football/2019/may/31/atletico-madrid-stadium-wanda…litano-champions-league-final-liverpool-tottenham", type: "article", sectionId: "football", sectionName: "Football", webPublicationDate: "2019-05-31T08:23:15Z", …}
2: {id: "tv-and-radio/2019/may/31/a-sinister-tale-from-the-minds-behind-dirty-john-podcasts-of-the-week", type: "article", sectionId: "tv-and-radio", sectionName: "Television & radio", webPublicationDate: "2019-05-31T08:12:02Z", …}
3: {id: "politics/2019/may/31/alastair-campbell-labour-expulsion-discrimination-appeal", type: "article", sectionId: "politics", sectionName: "Politics", webPublicationDate: "2019-05-31T08:11:22Z", …}
4: {id: "football/from-the-archive-blog/2019/may/31/womens-football-match-crouch-end-1895", type: "article", sectionId: "football", sectionName: "Football", webPublicationDate: "2019-05-31T08:00:27Z", …}
5: {id: "culture/2019/may/31/what-to-see-this-week-in-the-uk", type: "article", sectionId: "culture", sectionName: "Culture", webPublicationDate: "2019-05-31T08:00:27Z", …}
6: {id: "tv-and-radio/2019/may/31/when-they-see-us-review-netflix-ava-duvernay-central-park-five", type: "article", sectionId: "tv-and-radio", sectionName: "Television & radio", webPublicationDate: "2019-05-31T08:00:27Z", …}
7: {id: "music/2019/may/31/lee-scratch-perry-rainford-review-on-u-sound-records", type: "article", sectionId: "music", sectionName: "Music", webPublicationDate: "2019-05-31T08:00:27Z", …}
8: {id: "books/2019/may/31/mother-ship-francesca-segal-review", type: "article", sectionId: "books", sectionName: "Books", webPublicationDate: "2019-05-31T07:58:27Z", …}
9: {id: "football/2019/may/31/football-transfer-rumours-spurs-to-bid-for-wilfried-zaha", type: "article", sectionId: "football", sectionName: "Football", webPublicationDate: "2019-05-31T07:47:36Z", …}
length: 10
__proto__: Array(0)
startIndex: 1
status: "ok"
total: 2117063
userTier: "developer"
__proto__: Object
__proto__: Object

对不起,我忘了包含我的代码的这部分,这是我初始化this.state.news。 这里是

constructor() {
        super()

        this.state = {
            news: []
        }

        this.renderNews = this.renderNews.bind(this)
    }

这会产生因为在渲染时数据还没有准备好。

您可以根据自己的需要做各种事情。

1°。 state = { news: [] }类的默认状态声明为空数组。

2º。 在渲染方法中渲染某种加载,如if (!this.state.news.length) { return "Loading..." }

我看到你已经和每个新闻项目排列,所以你也应该控制它。

state = { news: { data: [] } }

你看,你将setState data设置为新闻作为对象属性,然后你尝试用map迭代它。 你不能这样做。

问题是在获取数据之前调用render。 我建议在组件中添加一个构造函数,并将消息初始化为空数组:

constructor() {
  super();
  this.state = {
    news: []
  };
}

如果你想正确地做,你可以为你的州添加一个加载属性:

constructor() {
  super();
  this.state = {
    loading: true,
  };
}

componentDidMount() {
  fetch('https://content.guardianapis.com/search?api-key=test')
    .then(response => response.json())
    .then(data => {
      this.setState({
        news: data,
        loading: false,
      });
      console.log(data);
    });
}

render() {
  const { loading } = this.state;
  return (
    <div>
      {loading ? (
        <h1>Loading...</h1> {/* Or use a loading icon or gif */}
      ) : (
        <div className="newsWrapper">
          <h3>{this.renderNews()}</h3>
        </div>
      )}
    </div>
  );
}

这样您的UI将更加用户友好。

在渲染期间,新闻数组不存在因此它为空,以解决此问题

renderNews() {
        const { news = [] } = this.state; // assign a default value
        return news.map((a, i) => (
            <div key={i}>
                {a.response.map((b, i) => (
                    <div key={i}>
                        <div key={i} className="newsEach">
                            <h3>{b.webTitle}</h3>
                            <ul className="newsInfoUl">
                                <li className="newsInfoEach">{b.type}</li>
                                <li className="newsInfoEach">
                                    {b.sectionName}
                                </li>
                                <li className="newsInfoEach">{b.pillarName}</li>
                                <li className="newsInfoEach">{b.webUrl}</li>
                            </ul>
                        </div>
                    </div>
                ))}
            </div>
        ))
    }

因为this.state.news是一个对象。 在你的setState ,我认为你期待data.results (这是一个数组)而不仅仅是data

this.setState({
  news: data.results,
  loading: false
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM