드디어 무한 스크롤이 두 번씩 발동되던 버그를 고쳤다.
고쳤다고 하기엔 아직 문제가 있어, 사실 응급처치라고 해도 될 것 같다.
결론부터 말하면,
기존 무한스크롤에서는, useQuery의 isLoading과 isFetchig이 끝났을 때 ref를 생성하여 무한스크롤을 동작시키고 있었다.
여기서 문제가 있었던게 isLoading과 isFetching은 끝났어도 요소가 아직 생성되지 않은 상태에서 ref가 생성되니, ref를 또 참조하게 되어 두 번씩 작동하던것.
처음에는, throttle을 주는 시점이 잘못된 줄 알고 offset을 증가하는 함수에서 Intersection Observer로 ref를 감지하는 함수로 throttle을 옮겨도 보고, 직접 throttle을 만들어도보고, 시간 조절도 해 봤으나 고쳐지지 않았다.
throttle 함수
const throttledLoadMore = throttle(() => {
if (isNextPage && !isFetching && !isLoading) {
// 이전 offset에 size를 더하여 다음 페이지 데이터를 가져오도록 설정
setOffset((prevOffset) => prevOffset! + size);
}
}, 1000);
두 번째로는 ref가 계속 생성되어 throttle이 먹지 않는가 싶어 ref를 조건부 렌더링이 아닌 위 코드처럼 함수 자체에 조건을 줘보았으나, 이 또한 아니었다.
몇일이 지난 오늘, 마지막으로 state를 사용하여 loading 완료 여부를 직접 조작 하였더니 드디어 한 번에 한 번만 작동하게 되었다!!
기존 코드
const animeListQueryOptions = {
queryKey: animeListQueryKey,
queryFn: () => fetchAnimeList(params);
refetchOnWindowFocus: false,
onSuccess: (data: any) => {
setIsNextPage(data.isNextPage);
setCount(data.count);
setAnimeList((prevAnimeList) => [...prevAnimeList, ...data.animeList]);
},
};
// query로 데이터를 받아와 set해준다.
....
{!isLoading && isNextPage && <S.Target ref={ref} />}
// loading이 끝나고 nextpage가 있다면 ref를 생성한다.
수정 된 코드
const [isLoaded, setIsLoaded] = useState(false);
const animeListQueryOptions = {
queryKey: animeListQueryKey,
queryFn: async () => {
setIsLoaded(false);
const data = await fetchAnimeList(params);
return data;
},
refetchOnWindowFocus: false,
onSuccess: (data: any) => {
setIsNextPage(data.isNextPage);
setCount(data.count);
setAnimeList((prevAnimeList) => [...prevAnimeList, ...data.animeList]);
setIsLoaded(true);
},
};
// isLoaded란 state를 추가.
// queryFn을 실행할 때 false를 주고, onSuccess를 통해 true를 준다.
......
<S.Target ref={ref} />
// ref는 항상 생성되어 있고,
const throttledLoadMore = throttle(() => {
if (isNextPage && !isFetching && !isLoading && isLoaded) {
// 이전 offset에 size를 더하여 다음 페이지 데이터를 가져오도록 설정
setOffset((prevOffset) => prevOffset! + size);
}
}, 1000);
// 함수에 조건을 붙여 로딩이 모두 끝나야만 offset을 증가시킨다.
'기록 > TIL' 카테고리의 다른 글
HTTPS : (0) | 2023.10.18 |
---|---|
DDD : Domain Driven Design (0) | 2023.10.17 |
2023.09.20 (0) | 2023.09.20 |
2023.09.15 useMemo로 최적화 해보기 (0) | 2023.09.15 |
2023.09.13 (0) | 2023.09.13 |