외부 API 연동

Posted by yunki kim on July 12, 2021

axios를 설치하고 다음과 같은 코드를 작성하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import logo from './logo.svg';
import './App.css';
import React, {useState} from 'react';
import axios from 'axios';
 
function App() {
  const [data, setDate] = useState(null);
      const onClick = async () => {
          try{
              //  가짜 API를 호출할 수 있는 사이트
              const response = axios.get('https://jsonplaceholder.typicode.com/todos/1');
              setDate(response.data);
          }
          catch(err) {
              console.error(err);
          }
      }
 
  return (
      <div>
        <div>
          <button onClick={onClick}>call</button>
          {data && <textarea rows={7} value={JSON.stringify(data, null2)} readOnly={true/>}
        </div>
      </div>
  );
}
 
export default App;
 
cs

그후 https://newsapi.org

 

News API – Search News and Blog Articles on the Web

Get JSON search results for global news articles in real-time with our free News API.

newsapi.org

에 들어가서 회원가입을 하면 API키를 발급받을 수 있다.

그 후 https://newsapi.org/s/south-korea-news-api

 

News API – Search News and Blog Articles on the Web

Get JSON search results for global news articles in real-time with our free News API.

newsapi.org

에 들어가 url을 복사하고 위 코드의 axios부분에 이 url을 넣어 준다. 그 후 src/Components에 NewsItem.js를 만든다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//NewsItem.js
import
 React from 'react';
import styled from 'styled-components';
 
const NewsItemBlock = styled.div`
    display: flex;
  
    .thumbnail {
      margin-right: 1rem;
      img {
        display: block;
        width: 160px;
        height: 100px;
        object-fit: cover;
      }
    }
  .contents {
    h2 {
      margin: 0;
      a {
        color: black;
      }
    }
    p {
      margin: 0;
      line-height: 1.5;
      margin-top: 0.5rem;
      white-space: normal;
    }
  }
  & + & {
    margin-top: 3rem;
  }
`;
 
const NewsItem = ({article}) => {
    const {title, description, url, urlToImage} = article;
    return (
      <NewsItemBlock>
          {urlToImage && (
              <div className="thumbnail">
                  <a href={url} target={"_blank"} rel={"noopener noreferrer"}>
                      <img src={urlToImage} alt="thumbnail"/>
                  </a>
              </div>
          )}
          <div className="contents">
              <h2>
                  <a href={url} target={"_blank"} rel={"noopener noreferrer"}>
                      {title}
                  </a>
              </h2>
              <p>{description}</p>
          </div>
      </NewsItemBlock>
    );
}
 
export default NewsItem;
cs

이제 NewsList.js를 만들고 내부에서 API연동을 진행한다. 이때 axios를 그냥 async를 이용하면 안된다. useEffect는 clean-up함수를 반환하고 있기 때문이다. 따라서 useEffect 내부에서 async/await를 사용하고 싶다면 함수 내부엣 async가 붙은 또 다른 함수를 만들어서 사용해야 한다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//NewsList.js
import React, {useState, useEffect} from 'react';
import styled from 'styled-components';
import NewsItem from './NewsItem';
import axios from 'axios';
 
const NewsListBlock = styled.div`
  box-sizing: border-box;
  padding-bottom: 3rem;
  width: 768px;
  margin: 0 auto;
  margin-top: 2rem;
  @media screen and (max-width: 768px) {
    width: 100%;
    padding-left: 1rem;
    padding-right: 1rem;
  }
`;
 
const NewsList = () => {
    const [articles, setArticles] = useState(null);
    //API요청이 대기 중인지 판별
    const [loading, setLoading] = useState(false);
    useEffect(() => {
        const fetchData = async() => {
            setLoading(true);
            try{
                const res = await axios.get(
                    'https://newsapi.org/v2/top-headlines?country=kr&apiKey=2c88868b5a4e44dcaa072c55dac0b307'
                );
                setArticles(res.data.articles);
            }
            catch(err) {
                console.error(err);
            }
            setLoading(false);
        };
        fetchData();
    }, []);
 
    if(loading) {
        return <NewsList>Loading...</NewsList>
    }
 
    if(!articles){
        return null;
    }
 
    return (
        <NewsListBlock>
            {articles.map((article) => (
                <NewsItem key={article.url} article={article}/>
            ))}
        </NewsListBlock>
    );
};
 
export default NewsList;
cs