관리 메뉴

거니의 velog

(2) 외부 API를 연동하여 뉴스 뷰어 만들기 2 본문

React/React_뉴스 뷰어 앱 만들기

(2) 외부 API를 연동하여 뉴스 뷰어 만들기 2

Unlimited00 2023. 12. 12. 17:13

3. newsapi API 키 발급받기

* 이번 프로젝트에서는 newsapi에서 제공하는 API를 사용하여 최신 뉴스를 불러온 후 보여 줄 것이다. 이를 수행하기 위해서는 사전에 newsapi에서 API 키를 발급받아야 한다. API 키는 아래 주소로 가입하면 발급받을 수 있다.

https://newsapi.org/register

 

Register - News API

Email addresses will be verified, please enter a real one. Disposable addresses have been blocked. Reminder: If you are a business or are using News API commercially then a subscription is required to continue using the API outside of development.

newsapi.org

newsapi 가입
newsapi 가입 완료

https://newsapi.org/account

 

Login - News API

 

newsapi.org


* 발급받은 API 키는 추후 API를 요청할 때 API 주소의 쿼리 파라미터로 넣어서 사용하면 된다.

* 이제 우리가 사용할 API에 대해 알아보자. 아래 링크로 들어가면 한국 뉴스를 가져오는 API에 대한 설명서가 있다.

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

 

South Korea News API - Live top headlines from South Korea

Get live top and breaking news headlines from South Korea with our JSON API. Live example This example demonstrates the HTTP request to make, and the JSON response you will receive, when you use the News API to get live headlines from South Korea. Top head

newsapi.org

한국 뉴스 API 설명서

* 사용할 API 주소는 두 가지 형태이다.

1. 전체 뉴스 불러오기

GET https://newsapi.org/v2/top-headlines?country=kr&apiKey=8aa6de08f72745be9bbb2a4e91ef45ae
2. 특정 카테고리 뉴스 불러오기

GET https://newsapi.org/v2/top-headlines?country=kr&category=business&apiKey=8aa6de08f72745be9bbb2a4e91ef45ae

* 여기서 카테고리는 busuness, entertainment, health, science, sports, technology 중에 골라서 사용할 수 있다. 카테고리를 생략하면 모든 카테고리의 뉴스를 불러온다. apiKey 값에는 앞에서 여러분이 발급 받았던 API 키를 입력해 주면 된다.

* 이제 기존에 리액트 프로젝트에서 사용했던 JSONPlaceholder 가짜 API를 전체 뉴스를 불러 오는 API로 대체해 보자.

[App.js]

import React, { useState } from 'react';
import axios from '../node_modules/axios/index';

const App = () => {
  const [data, setData] = useState(null);
  const onClick = async () => {
    try {
      const response = await axios.get(
        'https://newsapi.org/v2/top-headlines?country=kr&apiKey=8aa6de08f72745be9bbb2a4e91ef45ae',
      );
      setData(response.data);
    } catch (e) {
      console.log(e);
    }
  };
  return (
    <div>
      <div>
        <button onClick={onClick}>불러오기</button>
      </div>
      {data && (
        <textarea
          rows={7}
          value={JSON.stringify(data, null, 2)}
          readOnly={true}
        ></textarea>
      )}
    </div>
  );
};

export default App;

newsapi 호출

* 데이터가 잘 나타나는가? 이제 이 데이터를 화면에 예쁘게 보여 주면 된다.


4. 뉴스 뷰어 UI 만들기

* styled-components를 사용하여 뉴스 정보를 보여 줄 컴포넌트를 만들어 보자. 우선 styled-components를 설치해 주자.

$ yarn add styled-components

* 그리고 src 디렉터리 안에 components 디렉터리를 생성한 뒤, 그 안에 NewsItem.js 와 NewsList.js 파일을 생성하자.

* NewsItem은 각 뉴스 정보를 보여 주는 컴포넌트이고, NewsList는 API를 요청하고 뉴스 데이터가 들어 있는 배열을 컴포넌트 배열로 변환하여 렌더링해 주는 컴포넌트이다.


(1) NewsItem 만들기

* 먼저 NewsItem 컴포넌트 코드를 작성해 보자. 그 전에 각 뉴스 데이터에는 어떤 필드가 있는지 확인해 보자.

{
    "source": {
        "id": null,
        "name": "Hani.co.kr"
    },
    "author": null,
    "title": "[포토] 이낙연 전 대표가 활짝 반긴 이 사람은 - 한겨레",
    "description": "이낙연 전 더불어민주당 대표가 민주당을 탈당한 이상민 의원과 만났다.  무소속 이 의원은 11일 오후 2시께 서울 종로구에 ...",
    "url": "https://www.hani.co.kr/arti/politics/assembly/1119902.html",
    "urlToImage": "https://flexible.img.hani.co.kr/flexible/normal/970/664/imgdb/original/2023/1211/20231211502075.jpg",
    "publishedAt": "2023-12-11T06:25:26Z",
    "content": "a').text() + '_' + $(this).find('a').text());\"&gt;\r\n ·\r\n[] \r\n2023-12-11 15:252023-12-11 15:31"
}

* 위 코드는 각 뉴스 데이터가 지니고 있는 정보로 이루어진 JSON 객체이다. 그 중에서 다음 필드를 리액트 컴포넌트에 나타낼 것이다.

- title : 제목

- description : 내용

- url : 링크

- urlToImage : 뉴스 이미지

* NewsItem 컴포넌트응 article이라는 객체를 props 통째로 받아 와서 사용한다. NewsItem 컴포넌트를 다음과 같이 작성해 보자.

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="_black" rel="noopener noreferrer">
            {title}
          </a>
        </h2>
        <p>{description}</p>
      </div>
    </NewsItemBlock>
  );
};

export default NewsItem;

(2) NewsList 만들기

* 이번에는 NewsList 컴포넌트를 만들어 보자. 나중에 이 컴포넌트에서 API를 요청하게 될텐데, 지금은 아직 데이터를 불러오지 않고 있으니 sampleArticle이라는 객체에 미리 예시 데이터를 넣은 후 각 컴포넌트에 전달하여 가짜 내용이 보이게 해 보자.

import React from 'react';
import styled from 'styled-components';
import NewsItem from './NewsItem';

const NewsListBlock = styled.div`
  box-sizing: border-box;
  padding-bottom: 3rem;
  width: 768px;
  margin: 0 auto;
  margin-top: 2rem;
  @media all and (max-width: 768px) {
    width: 100%;
    padding-left: 1rem;
    padding-right: 1rem;
  }
`;

const sampleArticle = {
  title: '제목',
  description: '내용',
  url: 'https://google.com',
  urlToImage: 'https://via.placeholder.com/160',
};

const NewsList = () => {
  return (
    <NewsListBlock>
      <NewsItem article={sampleArticle} />
      <NewsItem article={sampleArticle} />
      <NewsItem article={sampleArticle} />
      <NewsItem article={sampleArticle} />
      <NewsItem article={sampleArticle} />
      <NewsItem article={sampleArticle} />
    </NewsListBlock>
  );
};

export default NewsList;

* 다 만든 뒤에는 이 컴포넌트를 App 컴포넌트에서 보여 주자. App 컴포넌트에 기존에 작성했던 코드는 모두 지우고, NewsList만 렌더링해 보자.

import React from 'react';
import NewsList from './components/NewsList';

const App = () => {
  return <NewsList />;
};

export default App;

NewsList UI

* 컴포넌트들이 잘 나타났는가?