본문 바로가기
에러 디버깅 & 리팩토링

Intersection Observer API로 무한스크롤 구현하기 / 비동기 네트워크 요청 버그 해결

by growingTangerine 2023. 5. 30.

<문제 상황>

의도한 코드 - 페이지가 처음 렌더링 되었을 때, page 파라미터가 없는 요청이 1회 발생 -> 스크롤을 아래로 내렸을 때, page=2 를 파라미터로 갖는 요청이 1회 발생

 

실제 동작 - 페이지가 처음 렌더링 되었을 때, page 파라미터가 없는 요청과 page=1 파라미터를 갖는 요청이 두번 발생 (이건 strict mode 때문에 개발 환경에서만 발생) / 스크롤을 아래로 내리기 전에도 page=2를 파라미터로 갖는 요청이 1회 발생

<문제 파악>

fetch 요청이 작성된 코드는 아래 두 부분이다.

1. 초기 요청 (파라미터 X)

2. 페이지 수 증가 시 요청 발생

우선, useEffect의 특성을 잘못 파악하고 있었다. 2번 요청은 페이지가 렌더링 되었을 때, 즉 page 상태값이 1일 때에도 한번 발생한다. 따라서, 1번 요청은 굳이 따로 작성해줄 필요가 없는 것이었다. 

 

1번 요청을 주석처리하고 다시 네트워크 탭을 보았더니, 이번에는 page=1인 요청과 page=2인 요청이 발생했다. 

이 말인 즉슨, intersection observer를 세팅한 아래 코드인 useEffect가 첫 렌더링 시에 effect를 발생시킨다는 것이다.

 

내 예상은 첫 렌더링 시에는 div가 viewport에서 관측되지 않으므로, isIntersecting === false라서 setPage가 호출되지 않는 것이었다. 하지만, 네트워크 요청은 비동기적으로 발생하므로 첫 렌더링 시 찰나의 순간이지만 div가 맨 위 상단에 위치하게 되어, isIntersecting이 true가 되어버린다. 그래서 setPage가 호출되고, page=2인 상태를 갖는 fetch요청이 발생한 것이다.

 

<문제 해결>

해결 방법을 두가지 생각해보았다.

 

1. 네트워크 요청을 동기화
2. target 요소를 네트워크 요청 이후에 잡히는 요소로 변경

 

하나씩 적용해서 살펴보자.

 

우선 1번을 적용해보았다.

하나로 합쳐준 fetch 요청에 async, await 구문을 추가해준 후에 네트워크 탭을 살펴보니 page=2에 해당하는 네트워크 요청이 발생하지 않았다. 

 

2번은 적용해보지는 않았지만, 같이 무한스크롤 구현 챌린지를 한 동기가 2번의 방식으로 코드를 작성했다. target 요소를 네트워크 요청으로 불러와서 렌더링한 영화 카드의 마지막에서 4-5번째쯤 요소로 잡아주면 된다. 

 

해결 완료 !!!!!!