리액트 & 넥스트 & 리덕스 & 리덕스사가 & 익스프레스 스택으로 트위터와 유사한 SNS 서비스를 만들어봅니다. 끝으로 검색엔진 최적화 후 AWS에 배포합니다.
Intersection Observer 소스 코드 추가했습니다.
https://github.com/ZeroCho/react-nodebird/tree/master/intersection
문의하시는 분들(인피니트 스크롤링에서 height 소수점 발생 문제나 쓰로틀링 적용 안 됨 등의 문제가 발생하시는 분)이 많아서 인터섹션옵저버 적용한 소스코드 공유합니다.
훨씬 더 인피니트 스크롤링을 간단하게 적용하실 수 있습니다. 간단히 설명드리자면,
먼저 react-intersection-observer 패키지를 설치하고(react에서는 dom에 접근하려면 ref를 사용해야하는데 패키지를 안 쓰고도 할 수 있으나 조금 귀찮습니다)
다음 코드를 window.addEventListener('scroll')이 있는 useEffect 대신 넣으시면 됩니다.
const [ref, inView] = useInView();
useEffect(
() => {
if (inView && hasMorePosts && !loadPostsLoading) {
const lastId = mainPosts[mainPosts.length - 1]?.id;
dispatch({
type: LOAD_POSTS_REQUEST,
lastId,
});
}
},
[inView, hasMorePosts, loadPostsLoading, mainPosts, id],
);
JSX단에서는 다음과 같이 넣어주세요.
{mainPosts.map((post) => <PostCard key={post.id} post={post} />)}
<div ref={hasMorePosts && !loadPostsLoading ? ref : undefined} />
PostCard들 아래에 위치한 div가 화면에 보이는 순간(즉, 마지막 게시글을 봤다는 소리겠죠) inView가 true가 되면서 useEffect가 작동합니다. inView가 true고, 게시글이 더 있고, 로딩중이 아니라면 새 게시글을 가져오는 액션이 dispatch 됩니다.
ref props를 보시면 hasMorePosts && !loadPostsLoading ? ref : undefined로 되어있는데 게시글이 더 있고, 로딩중이 아닐 때에만 ref가 연결되기 때문에 이 상황이 아니면 intersectionObserver가 해제됩니다.
현재는 가장 마지막 게시글보다 더 아래로 내려야만 인피니트 스크롤링이 작동하지만, 만약 아래에서 두번째, 아래에서 세 번째 등의 기준을 두고 싶으시다면 mainPosts.map 사이에 div를 끼어넣거나, 특정 인덱스의 PostCard의 ref로 인터섹션옵저버의 ref를 전달하시면 됩니다.