반응형
비동기 방식 통신의 대표적인 API를 활용하는 예제로 newsapi 를 이용하여 전체 뉴스와 특정 카테고리 뉴스를 불러와서 보여주는 프로젝트를 만들어 봅니다.
1. newsapi key 발급받기
발급받은 API 키는 API를 요청할 때 API 주소의 쿼리 파라미터로 넣어서 사용하면 됩니다.
한국 뉴스를 가져오는 API 설명서는 아래의 링크에서 확인 가느합니다.
https://newsapi.org/s/south-korea-news-api
- 전체 뉴스 불러오기 (예시)
GET https://newsapi.org/v2/top-headlines?country=kr&apiKey=1ea3c5d642534097a4ae5a32303b16d8 - 특정 카테고리 뉴스 불러오기 (예시)
GET https://newsapi.org/v2/top-headlines?country=kr&category=business&apiKey=1ea3c5d642534097a4ae5a32303b16d8
카테고리 종류 - business, entertainment, health, science, sports, technology
import { useState } from 'react';
import axios from 'axios';
function App() {
const [data, setData] = useState(null);
const onClick = async () => {
try {
const response = await axios.get(
'https://newsapi.org/v2/top-headlines?country=kr&apiKey=발급받은key',
);
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}
/>
)}
</div>
);
}
export default App;
2. 뉴스 뷰어 UI 만들기
styled-components 사용하여 뉴스 뷰어 컴포넌트를 만듭니다. 우선 styled-components 를 설치합니다.
>npm i styled-components
2-1. NewsItem 만들기
{
"source": {
"id": null,
"name": "Yonhapnewstv.co.kr"
},
"author": null,
"title": "선관위·감사원 '감사' 두고 충돌…여야, 국정조사 추진 - 연합뉴스TV",
"description": "선관위·감사원 '감사' 두고 충돌…여야, 국정조사 추진\n\n[앵커]\n\n자녀 특혜 채용 의혹을 받는 선거관리위원회가 감사원 감사 수용 불가로 최종 결론을 냈습니다.\n\n감사원이 즉각 반",
"url": "https://www.yonhapnewstv.co.kr/news/MYH20230602018700641",
"urlToImage": "https://yonhapnewstv-prod.s3.ap-northeast-2.amazonaws.com/article/MYH/20230602/MYH20230602018700641_P1.jpg",
"publishedAt": "2023-06-02T10:12:46Z",
"content": "<ul><li>()TV 2()\r\n</li><li> : </li><li> : 02-398-7800</li><li> : 101-86-62619</li></ul>\r\nCopyright 2019 © TV :: . 23 All rights reserved.\r\n () , ·· ."
},
API 로 불러온 JSON 객체로 다음 필드를 리액트 컴포넌트에 표출하도록 하겠습니다.
- title : 제목
- description : 내용
- url : 링크
- urlToImage : 뉴스이미지
우선 전체 뉴스에 해당하는 article 객체(뉴스 리스트 전체)를 props로 받아와서 사용합니다.
NewsItem 컴포넌트를 다음과 같이 만듭니다.
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="_black" 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;
이번에는 NewsList 컴포넌트를 만들겠습니다. 이 컴포넌트에서 API를 요청하겠지만 우선 샘플 데이터로 화면만 구성해보겠습니다.
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 screen 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컴포넌트에서 기존 작성했던 것 지우고 NewsList가 보이도록 바꿔줍니다.
import NewsList from './components/NewsList';
function App() {
return <NewsList />;
}
export default App;
뉴스 목록이 만들어 졌습니다. 이제 API 를 불러와서 뉴스를 표출하는 것은 다음 블로그에서 이어서 작성하도록 하겠습니다.
반응형
'리액트(React)' 카테고리의 다른 글
리액트로 뉴스뷰어 만들어 보기(3) (0) | 2023.06.06 |
---|---|
리액트로 뉴스뷰어 만들어 보기(2) (0) | 2023.06.06 |
리액트(React) axios 로 API 호출하기 (0) | 2023.06.01 |
리액트(React) 비동기 작업 - 콜백함수, Promise, async/await (0) | 2023.05.29 |
리액트 라우터(React Router) 부가기능 활용 (0) | 2023.05.29 |