从NewsApi中获取数据(反应,axios)

时间:2020-03-06 16:04:49

标签: javascript reactjs api axios fetch

我已经开始学习反应,现在我正在处理代码挑战。

我的任务是使用Axios列出newsapi.org中的数据。有10条文章要显示,并且列表应该可以扩展(加载更多)。

现在我无法再显示数据了。

我的错误在哪里?

这是我的代码:

import React from "react";
import axios from "axios";

class App extends React.Component {
  state = {
    articles: [],
    isLoading: true,
    errors: null
  };

  getArticles() {
    axios
      .get(
        "http://newsapi.org/v2/everything?q=ai&apiKey=XXXXXXXXX"
      )
      .then(response =>
        response.data.results.map(article => ({
          date: `${article.publishedAt}`,
          title: `${article.title}`,
          url: `${article.url}`
        }))
      )
      .then(articles => {
        this.setState({
          articles,
          isLoading: false
        });
      })
      .catch(error => this.setState({ error, isLoading: false }));
  }

  componentDidMount() {
    this.getArticles();
  }

  render() {
    const { isLoading, articles } = this.state;
    return (
      <React.Fragment>
        <h2>#AI</h2>
        <div>
          {!isLoading ? (
            articles.map(article => {
              const { date, title, url } = article;
              return (
                <div key={title}>
                  <p>{date}</p>
                  <p>{title}</p>
                  <p>{url}</p>
                </div>
              );
            })
          ) : (
            <p>Loading...</p>
          )}
        </div>
      </React.Fragment>
    );
  }
}
export default App;

3 个答案:

答案 0 :(得分:2)

您必须使用response.data。文章而不是结果

答案 1 :(得分:0)

正如Kevin所提到的,首先您需要映射response.data.articles,但还必须返回映射的结果,否则当您调用.then设置状态时,它将是undefined 。像这样:

getArticles() {
  axios
    .get(
      "https://newsapi.org/v2/everything?q=ai&apiKey=YOURAPIKEYGOESHERE"
    )
    .then(response => {
      return response.data.articles.map(article => ({
        date: `${article.publishedAt}`,
        title: `${article.title}`,
        url: `${article.url}`
      }));
    })
    .then(articles => {
      this.setState({
        articles,
        isLoading: false
      });
    })
    .catch(error => this.setState({ error, isLoading: false }));
}

现在应该可以使用。

答案 2 :(得分:0)

嗨,尝试使用fetch()方法,请参见下面的代码。

Andrei的robofriends教程的部分代码。使用相同的圆锥形

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>

import React, {Component} from 'react';
import CardList from '../components/Cardlist';
import SearchBox from '../components/SearchBox';
import './App.css';
import Scroll from '../components/Scroll';
import ErrorBoundry from '../components/ErrorBoundry';


class App extends Component {
    //add state
    constructor() {
        super()
        this.state = {
            articles: [],
            searchfield: ''
        }
    }

    componentDidMount() {
        //fetch is a window object
        fetch('https://newsapi.org/v2/top-headlines?country=gb&category=business&apiKey=yourapikey')
        .then(response => response.json()) //convert to json
        //.then(users =>this.setState({ news: users}));
        .then(res => {
            const articles = res.articles;
            // Set state with result
            console.log(articles);
            this.setState({ articles: articles });
          })
    }


    //event for searchbox change
    //not part of react component so use arrow function
    onSearchChange = (event) => {
        this.setState({ searchfield: event.target.value})
    }

    render() {
        const filteredNews = this.state.articles.filter(i => {
            return i.source.name.toLowerCase().includes(this.state.searchfield.toLowerCase()); //change name to source?
        })
        console.log(filteredNews);
        if (this.state.articles.length === 0) {
            return <h1>Loading Robots</h1>
        } else {
            return (
                <div className='tc'>
                    <h1 className='f1'>Top Headlines</h1>
                    <SearchBox  searchChange={this.onSearchChange}/>
                    <Scroll>
                        <ErrorBoundry>
                            <CardList articles={filteredNews}/>
                        </ErrorBoundry> 
                    </Scroll>
                </div>
                
            );
        }
        
    }   
}

export default App;