📑 무한 스크롤(Infinite sroll)을 지원하는 News Viewer를 구현해 보자!
뉴스 API를 가져와 5개씩 보여주고, 스크롤이 화면의 가장 아래쪽에 닿을 때, 또 다른 기사 5개를 띄워주는 무한스크롤 news를 만들어보고자 한다.
✨ 결과물
✅ 이미지와 내용의 경우, API의 문제로 인해 제대로 띄워지지 않아 회색 배경의 이미지와 빈문자열로 대체하였다.
open news API에서 가져올 수 있는 정보는 title 정도여서 제목만 띄워놓은 결과물이다.
화면을 보면 전체 보기를 눌렀을 경우, 비즈니스, 엔터테인먼트, 건강, 과학 등 여러 개의 카테고리에서 랜덤으로 하나씩 나열하여 보여주고 있고, 나머지 카테고리에서는 해당하는 카테고리에 맞는 기사를 5개씩 보여주고 있다.
화면 아래에 스크롤이 닿았을 때는 Loading 중이라는 img를 띄워 사용자에게 로딩 중임을 알려주고, 새로운 기사를 5개씩 띄우는 식으로 구현하였다.
📌 2개의 컴포넌트로 News Viewer를 구성
👉🏻 뉴스의 카테고리를 나타내는 Nav와 해당 카테고리에 맞는 기사를 띄우는 NewsList 컴포넌트
// Nav
const categories = {
all: '전체보기',
business: '비즈니스',
entertainment: '엔터테인먼트',
health: '건강',
science: '과학',
sports: '스포츠',
technology: '기술',
};
.
.
.
// NewsList
async function NewsList() {
const root = document.getElementById('root');
const newsListContainer = makeDOM('div', {
className: 'news-list-container',
});
const newsList = makeDOM('article', {
className: 'news-list',
});
root.appendChild(Nav());
root.appendChild(newsListContainer);
newsListContainer.appendChild(newsList);
}
✅ Nav와 NewsList 컴포넌트를 각각 생성한 후, NewsList에서 Nav()를 appendChild로 추가하도록 구현하였다.
📌 News API를 사용해 뉴스를 취득
👉🏻 뉴스는 한 번 호출 시, 5개씩 호출하며 무한스크롤(Infinite Scroll)을 사용해 페이지네이션 기능 구현
News API – Search News and Blog Articles on the Web
“Ascender AI has a mission to apply AI to the media, and NewsAPI is one of our most valuable resources. Ascender is redefining how users interact with complex information, and the NewsAPI feed is an essential showcase for our technologies.” Braddock Ga
newsapi.org
✅ 해당 링크를 통해 회원가입을 진행 후, 본인의 API key를 받아 이를 활용해서 진행하면 된다.
(화면 구현 시, 잦은 API 호출로 인해 하루 지정된 제한 호출 수를 모두 사용할 경우를 대비하여 2-3개 정도 구현해 놓는 것이 좋다)
💚 뉴스 API 가져오기
// page를 1 증가시키면 다음 페이지의 뉴스를 취득한다.
const url = `https://newsapi.org/v2/top-headlines?country=kr&category=${category === 'all' ? '' : category}&page=${page}&pageSize=${pageSize}&apiKey=${apiKey}`
const newsRendering = async () => {
try {
const response = await axios.get(`https://newsapi.org/v2/top-headlines?country=kr&page=${page}&pageSize=${pageSize}&category=${category === 'all' ? '' : category}&apiKey=${apiKey}`);
const { articles } = response.data;
...
}
...
}
✅ 뉴스 API를 가져오기 위한 기본 정보인 page, pageSize 등을 해당 조건에 맞게 할당한 뒤, 'axios'를 통해 호출하였다.
articles를 구조분해할당으로 가져온 뒤, 이를 forEach문으로 돌려 html 화면을 구현하였다.
💚 Intersection Observer API를 통해 무한스크롤(Infinite Scroll) 구현하기
https://developer.mozilla.org/ko/docs/Web/API/Intersection_Observer_API
Intersection Observer API - Web API | MDN
Intersection Observer API는 타겟 요소와 상위 요소 또는 최상위 document 의 viewport 사이의 intersection 내의 변화를 비동기적으로 관찰하는 방법입니다.
developer.mozilla.org
(출처 : 설명 mdn Intersection Observer API 링크 참고)
// 기존 IntersectionObserver 삭제
if (intersectionObserver) {
intersectionObserver.disconnect();
}
// 새로운 IntersectionObserver 생성
intersectionObserver = new IntersectionObserver((items) => {
items.forEach(async (item) => {
if (item.isIntersecting) {
await newsRendering();
}
});
}, options);
intersectionObserver.observe(observerElement);
};
✅ IntersectionObserver를 구현한 후, 무한스크롤 DOM을 작성한 observerElement를 추가해 주었다.
(observerElement에 appendChild를 통해 Loading 띄우는 img도 추가해 주었다!)
const options = {
root: null,
rootMargin: '0px',
threshold: 0.8,
};
✅ img를 띄우는 options의 기본설정으로 교차 비율을 0.8로 지정해 주었다.
🫠 학습을 하면서 오픈 API를 가져오는 것에 살짝 겁을 먹고 있어서 그런지 긴장감을 갖고 시작했다..
생각보다 API를 가져오는 것은 쉬웠으나 무한스크롤을 적용하는 것이 살짝 어려웠다.
Proxy와 옵서버패턴을 통해 전역 상태로 관리해서 구현하고 싶었지만 감이 잡히지 않아 완성하지 못했다.. 😭😭
Proxy와 옵서버패턴에 대해서는 예시를 참고하면서 조금 더 학습하고 적용해야 할 것 같다!
'프로젝트 > 토이 프로젝트' 카테고리의 다른 글
[React + TypeScript] Todo-List (0) | 2023.04.30 |
---|---|
[React] 야구게임(BULLS AND COWS) (0) | 2023.04.28 |
[javascript] Calendar & DatePicker (0) | 2023.04.23 |
[javascript] star-rating (0) | 2023.04.22 |
[javascript] AnalogClock (0) | 2023.04.06 |