Tre 프로젝트 추억 부분에서 게시글 목록 리스트를 인피니트 스크롤로 구현하기 위해 정보를 찾아보았다.
검색 결과 대부분 Intersection Observer를 이용해 인피니트 스크롤링을 구현하였다. 다른 방법으로는 window.scrollY, document.documentElement.clientHeight, document.documentElement.scrollHeight을 이용한 구현 방법이었다.
먼저 공부를 위해 듣고 있었던 인프런 강의(ZeroCho님의 React로 NodeBird 만들기)에서는 window 객체와 document객체를 이용한 방법을 사용하셨다.
하지만 이 방법은 단점을 가지고 있으며 Tre 프로젝트에서는 맞지 않는 방법이었다.
그러므로 Intersection Observer 방법을 통해 구현하였다. 먼저 react-intersection-observer 패키지를 설치하여 dom에 쉽게 접근하였다.
const [ref, inView] = useInView();
const { mainPosts, hasMorePost, loadPostLoading } = useSelector(
(state) => state.post
);
useEffect(() => {
if (inView && hasMorePost && !loadPostLoading) {
const lastId = mainPosts[mainPosts.length - 1]?.id;
dispatch({
type: LOAD_POST_REQUEST,
lastId,
});
}
}, [inView, hasMorePost, loadPostLoading, mainPosts]);
...중간 생략...
{mainPosts.map((post, index) => (
<Card
key={post.id}
className="card-item">
</Card>
))}
<div ref={hasMorePost && !loadPostLoading ? ref : undefined} />
Card들 아래에 위치한 div가 화면에 보이는 순간 inView가 true가 되면서 useEffect가 작동하며 보여줄 게시글의 데이터가 더 존재하고(hasMorePost) 데이터가 로딩중이 아니라면(!loadPostLoading) dispatch를 통해 게시물의 데이터를 가져와서 보여주게 된다.
참고자료
https://ko.javascript.info/optional-chaining
https://velog.io/@suyeonme/react-Infinite-Scroll-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0
https://www.inflearn.com/course/%EB%85%B8%EB%93%9C%EB%B2%84%EB%93%9C-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%A6%AC%EB%89%B4%EC%96%BC/news