본문 바로가기
Project/[클론 코딩] 뉴스 뷰어

[클론 코딩] 뉴스 API와 UI 설계

by Bam_t 2021. 12. 30.
728x90

이번 포스트에서는 우리가 활용할 뉴스 API를 준비하고 그에 대한 ui 설계를 다루겠습니다.


1. API 키 발급

아래 사이트에서 가입을 하고 API키를 발급 받겠습니다.

https://newsapi.org/

 

News API – Search News and Blog Articles on the Web

News API is a simple, easy-to-use REST API that returns JSON search results for current and historic news articles published by over 80,000 worldwide sources. Worldwide Scale Search through hundreds of millions of articles in 14 languages from 55 countries

newsapi.org

가입하면 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

위의 링크 설명을 보니 다음과 같은 방식으로 불러올 수 있습니다.

GET https://newsapi.org/v2/top-headlines?country=kr&apiKey=본인API키

혹은

GET https://newsapi.org/v2/top-headlines?country=kr&category=카테고리명&apiKey=본인API키

카테고리는 비지니스, 엔터테인먼트, 건강, 과학, 스포츠, 기술 5가지 분야에서 고를 수 있습니다.

 

그러면 이전에 만들었던 가짜 API불러오는 것에서 뉴스 API로 교체해보겠습니다. 기존의 await axios.get(url)에서 url 부분만 변경해 주면 됩니다.

import React, {useState} from 'react';
import axios from 'axios';

const App = () => {
    const [data, setData] = useState(null);
    const onClick = async () => {
        try {
            const res = await axios.get(
                'https://newsapi.org/v2/top-headlines?country=kr&apiKey=d6e76706631d4059b20e981f9fc9b930'
            ); //뉴스 api url삽입

            setData(res.data);
        }
        catch (err) {
            console.log(err);
        }
    }

    return (
        <div>
            <div>
                <button onClick={onClick}>불러오기</button>
            </div>
            {data && <textarea rows={7} value={JSON.stringify(data, null, 2)} readOnly={true}/>}
        </div>
    );
};

export default App;

실행하고 불러오기 했을 때 뉴스의 내용이 나타난다면 성공적으로 API 연결에 성공한 것 입니다.

 

 

2. styled-components

이번에 이용할 방식은 styled-components입니다. styled-components는 컴포넌트 스타일링 방식의 일종으로 .js 파일 내부에 스타일을 정의하는 방식입니다.

css 파일을 따로 만들지 않고 하나의 .js파일에서 스타일링을 하므로 파일 구조가 복잡해지지 않는다는 장점이 있습니다. 우선 styled-components 사용을 위해 패키지를 설치해주세요.

yarn add styled-components

우선 지금은 설치만 하고 사용법은 잠시 후 컴포넌트를 만들며 알아보겠습니다.

 

 

3. 뉴스 UI 컴포넌트

우선 뉴스를 보여주는 UI를 설계하도록 하겠습니다. 여기에 이용할 컴포넌트는 지난번에 만든 TODO-LIST와 비슷한데요. NewsItem 컴포넌트와 NewsList 컴포넌트입니다.

NewsItem은 뉴스를 말합니다. 기사 사진, 제목, 내용이 보이는 뉴스 그 자체를 의미합니다. TODO-LIST의 TodoListItem이 되겠네요. NewsList는 이러한 NewsItem 컴포넌트들을 모아 리스트로 보여주는 것을 의미합니다. TODO-LIST의 TodoList의 역할을 합니다.

만들기 전에 Newsapi의 데이터를 살펴보겠습니다. articles라는 배열에 하나의 기사인 article이 있고, 하나의 기사에는 source, author, title, description, url, urlToImage, publishedAt, content가 있습니다. 이 중에서 우리는 title: 제목, description: 기사 내용, url: 기사 링크, urlToImage: 기사 이미지를 활용하겠습니다.

 

3-1. NewsItem 컴포넌트

NewsItem 컴포넌트에서는 api 요청을 통해 받은 json의 article 객체를 props로 받아와서 활용합니다. 그리고 여기서 styled-components를 이용합니다. 그리고 다음과 같이 사용합니다. 저 백틱(``)사이에 원하는 스타일 속성과 값을 넣어서 컴포넌트를 스타일링하면 됩니다. 이때 sass에서 사용하던 자기 자신을 선택하는 &도 사용이 가능합니다.

import styled from 'styled-component';
const 컴포넌트명 = styled.div``;

styled-components를 이용한 style입니다. (티스토리 코드블록이 문법을 지원하지 않아서 코드블록 색상이 제대로 표기 되지 않을 수도 있습니다.)

import React from 'react';
import styled from 'styled-components';

const NewsItemBlock = styled.div`
    display: flex;
  
  .thumnail {
    margin-right: 1rem;
    
    img {
      display: block;
      width: 160px;
      height: 100px;
      object-fit: cover;
    }
  }
  
  .contents {
    h2 {
      margin: 0;
      
      a {
        color: #000;
      }
    }
    
    p {
      margin: 0;
      line-height: 1.5;
      margin-top: 0.5rem;
      white-space: normal;
    }
  }
  
  & + & {
    margin-top: 3rem;
  }
`;

 

이어서 컴포넌트를 작성해보겠습니다. article을 받아와서, 기사 이미지/제목/내용을 렌더링합니다.

const NewsItem = ({article}) => {
    const {title, description, url, urlToImage} = article;

    return (
        <NewsItemBlock>
            {urlToImage && (
                <div className={"thumnail"}>
                    <a href={url} target={"_blank"} rel={"noopener noreferrer"}>
                        <img src={urlToImage} alt={"thumnail"}/>
                    </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;
<a href={url} target={"_blank"} rel={"noopener noreferrer"}>

herf는 article 객체의 url, 기사의 원본 url을 의미하고, target은 url을 연결하면 새 창에서 열기를 의미합니다.

rel의 노오프너(noopener)와 노리퍼러(noreferrer)는 보안상의 조작을 위한 방식입니다. 노오프너는 링크된 페이지에서 링크를 건 페이지(우리가 만드는 앱)를 참조하지 못하도록 합니다. 노리퍼러는 다른 페이지 이동시에 링크를 건 페이지의 정보를 송신하지 못하게 하는 옵션입니다.

 

3-2. NewsList 컴포넌트

이제 위에서 만든 NewsItem을 리스트 형식으로 보여줄 NewsList 컴포넌트를 작성해보겠습니다.

NewsList의 styled-components입니다.

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;
  }
`;

 

다음은 NewsList 컴포넌트입니다. 여기서 sampleArticle 객체는 이 단계에서 아직 api를 연동하기 이전이므로 우리의 결과를 확인하기 위해 만든 임시 기사 객체입니다.

const sampleArticle = {
    title: '제목',
    description: '내용',
    url: 'https://bamtory29.tistory.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}/>
        </NewsListBlock>
    );
};

export default NewsList;

 

이제 우리가 만든 두 컴포넌트가 잘 렌더링 되었는지 실행해봅시다. 이전에 테스트용으로 만들었던 내용인 App,js의 내용들을 모두 지우고 아래와 같이 바꿔준 후 yarn start를 통해 실행해주세요.

import React, {useState} from 'react';
import NewsList from './components/NewsList';

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

export default App;

위와 같이 그림이 나오며, 이미지나 기사 제목, 내용을 클릭했을 때 sampleArticle에 설정된 url로 이동이 된다면 성공한 것 입니다.


이번에는 전체적인 UI를 설계 했고 다음 포스트에서는 뉴스 api와 연동해서 본격적인 뉴스 뷰어를 만들어보겠습니다.

728x90

댓글