독서 모임 조회페이지를 무한 스크롤로 구현한 상태였다. 독서 모임 수정 페이지를 작업하다 독서 모임 조회페이지에서 마지막 아이템이 render 되는 위치(스크롤 최하단)의 아이템들은 수정이 되지 않는 문제를 발견했다. 어떤 문제가 발생했고 그 문제를 어떻게 해결하였는지 포스팅 해보려고 한다!
독서의 왕도 수정
이라고 모임 이름을 수정 했지만 업데이트 되지 않고 있다...🔎 스크롤이 최하단이 아닐때 보이는 리스트 아이템은?
- 스크롤이 최하단이 아닐 때 보이는 리스트 아이템 같은 경우 수정 작업 후 독서 모임 조회페이지 돌아왔을 때 수정된 데이터가 업데이트 되었다!
🔎 inview가 뭔가요?
- viewport에서 특정 요소(주로 위치를 하단에 설정)가 관찰되면 다음 데이터를 render하는 것이 무한 스크롤의 기본 원리다.
- 그러기 위해서는 특정 요소를
비동기
로 관찰하고 있어야만 한다.- 우리팀은 react-intersection-observer 라이브러리 도입 및 useInView Hook을 사용해 특정 요소 관찰 작업을 처리하기로 했다.
useInview
구성 요소
- ref : 관찰해야하는 요소의 ref props 값으로 설정하면 해당 요소는 관찰 대상이 된다.
- inView : viewport에서 등록한 요소가 관찰되면 true, 관찰되지 않으면 false를 반환하는 boolean 값
import { useInView } from 'react-intersection-observer';
const { ref, inView } = useInView();
// Bottom 컴포넌트가 viewport에서 관찰되면 다음 데이터를 fetch
useEffect(() => {
if (inView) fetchNextPage();
}, [fetchNextPage, inView]);
// Bottom 컴포넌트를 관찰대상으로
<Bottom ref={ref}>
{isFetchingNextPage && hasNextPage && 'Loading...'}
</Bottom>
👉 이제 문제 해결하로 가시죠!
useEffect(() => {
if (inView) {
console.log('next page');
fetchNextPage();
}
}, [fetchNextPage, inView]);
useEffect(() => {
if (!inView) return;
// fetch할 다음 데이터가 있을때만 fetchNextPage() 호출
// 마지막 아이템 같은 경우 hasNextPage가 false 이므로 fetchNextPage() 호출 x
hasNextPage && fetchNextPage();
}, [fetchNextPage, inView, hasNextPage]);
fetchNextPage 호출
이지만 구체적인 이유와 enabled에 의한 query 활성화
와의 인과관계를 정확히 파악하지는 못했다.query에 이전 데이터가 캐싱되어 있고 가져올 다음 페이지가 없을 때(마지막 아이템, 스크롤 최하단) 컴포넌트가 마운트 된 후 fetchNextPage()가 수행 => enabled에 의해 쿼리 활성화
이미 존재하는 데이터를 활용하여 컴포넌트가 렌더링됩니다. 하지만 실제로 새로운 데이터가 없으므로 화면에 변경된 내용은 없을 수 있습니다.
fetchNextPage와 enabled에 의한 쿼리 활성화가 동시에 발생하면 데이터 중복현상이 발생할 수 있음