newsapi API 키 발급받기
이번 프로젝트에서는 newsapi에서 제공하는 API를 사용하여 최신 뉴스를 불러온 후 보여 줄 것이다.
https://newsapi.org/login?ReturnUrl=%2faccount
Login - News API
newsapi.org
-components 폴더 생성
-NewsItems.js, NewsList.js 파일 생성
뉴스 뷰어 UI 만들기
NewsItem 만들기
각 뉴스 데이터가 지니고 있는 정보는 JSON 객체
-title : 제목
-description : 내용
-url : 링크
-urlToImage : 뉴스 이미지
-NewsItem 컴포넌트를 article 객체를 props로 통째로 받아서 사용
-a 태그의 rel 속성은 현재 문서와 링크 문서의 연관 관계를 명시 합니다.
-noreferrer : 사용자가 하이퍼링크를 클릭할 때 브라우저가 HTTP 리퍼러 헤더(referer header)를 전송해서는 안 됨을 나타냄.
-noopener : 하이퍼링크를 따라 연결되는 어떠한 브라우징 컨텍스트(browsing context)도 오프너(opener)여서는 안 됨을 나타냄.
NewsItems.js
import styled from 'styled-components';
const NewsItemBlock = styled.div`
display: flex;
margin-top: 3em;
.thumbnail {
margin-right: 1em;
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;
}
}
`;
//NewsList로부터 한개의 기사단위로 컴포넌트를 호출 받음
const NewsItem = ({article}) => {
const { title, description, url, urlToImage, source, author } = 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>
<p>{source.name}</p>
<p>{author}</p>
</div>
</NewsItemBlock>
);
};
export default NewsItem;
NewsList.js
import axios from "axios";
import { useEffect, useState } from "react";
import { UNSAFE_DataRouterStateContext } from "react-router-dom";
import styled from "styled-components";
import NewsItem from "./NewsItems";
const NewsListBlock = styled.div`
box-sizing: border-box;
padding-bottom: 3em;
width: 768px;
margin: 0 auto;
margin-top: 2rem;
@media screen and (max-width: 768px) {
width: 100%;
padding-left: 1em;
padding-right:1em;
}
`;
const NewsList = () => {
const [articles, setArticles] = useState(null);
const [loading, setLoading] = useState(false);
useEffect(() => { //화면이 렌더링 될 때 해야할 일을 여기서 구현
const fetchData = async () => { //useEffect Hook에서 async/await를 사용하기 위해서는 함수가 필요
setLoading(true); //화면이 로딩 중임을 표시 함
try { //서버에 대한 요청을 시도 함
const response = await axios.get(
"https://newsapi.org/v2/top-headlines?country=kr&apiKey=ffbbc82f694941a7b0e2d4f4515abcc7"
);
setArticles(response.data.articles); //동기처럼 보이지만 비동기로 결과를 받음, 랜더링이 일어남
//console.log(response.data.articles);
} catch (e) { //서버 요청이 실패 함
console.log(e);
}
setLoading(false);
};
fetchData();
}, []); //[]의존성 배열을 의미,
//배열을 비워두면 값이 변경된 상태를 체크하지 않기 때문에 화면이 나타날 때만
//해당 함수가 실행 됨
if(loading) {
return <NewsListBlock>로딩 중.........</NewsListBlock>
}
if(!articles) return null;
return(
<NewsListBlock>
{/* 서버로부터 데이터가 들어오면 map 함수를 순회하는 매개변수를 전달 함*/}
{articles.map(article =>(<NewsItem key={article.url} article={article}/>))}
</NewsListBlock>
)
}
export default NewsList;
App.js
import NewsList from "./components/NewsList";
const App = () => {
return <NewsList />
};
export default App;
'react' 카테고리의 다른 글
React (useState 사용하기) (0) | 2022.10.21 |
---|---|
CMD 창에서 프로젝트 생성하기 (0) | 2022.10.21 |
React (뉴스 가져오기, Styled Components) (0) | 2022.10.19 |
React (router) (0) | 2022.10.19 |