🔥 문제
Intersection.observer
의 unobserve
가 해당 callback
에서 제대로 작동하지 않았다.분기처리는 확실하나, 계속해서 새로운 요청이 들어온다. 이유가 무엇일까?
⭐ 해결 방법
해답은 공식 문서에서 찾을 수 있었다.
Intersection 옵저버는 결국, 대상요소와 상위요소, 그리고 뷰포트와 상위 요소에서 감시를 했을 때 해당 연산을 수행한다.
그런데 만약
callback
으로 인해 대상요소와 뷰포트가 변했다면 어떻게 될까?그 찰나의 시간 동안
observer
은 다음과 같이 판단한다.1. 응? 뭔가 바뀌었는데? 다시 판단해야겠는걸!
2. 그래~
unobserve
처리가 되도 마지막으로 한 번 판단하자! 개발자가 착각한 것일 수도 있잖아~따라서 의도치 않게,
observer
는 2번 실행된다. 바로 변하기 전과, 변하기 후에 말이다.따라서 계속해서 새로운 요청이 들어오는 것이었다.
그렇다면 진짜 해결 방법은?
결국 이 글을 보는 사람은 이를 원해서 들어왔을 것이다.
해결 방법은 매우 간단하다. 맨 처음부터 얼리리턴을 시켜버리면 그만인 것이다.
그러면 변한 이후에도 이미 조건에 맞지 않으므로 바로 리턴이 되어버릴 것이다!
const observerCallback = ( entries: IntersectionObserverEntry[], observer: IntersectionObserver ) => { entries.forEach((entry: IntersectionObserverEntry) => { // TODO: lastReviewId가 현재 마지막 리뷰와 같다면 early return한다. if (lastId.current > 3) { observer.unobserve(entry.target); } if (entry.isIntersecting) { // TODO: API 요청에 페이지를 담아 전달한다. cnt를 업데이트한다. (실제로는 마지막 리뷰 id) setNowReviews((state) => [...state, ...reviews]); lastId.current += 1; // TODO: 만약 요청을 했을 때 더이상 추가할 수 없다면 observe를 추가하지 않는다. if (lastId.current > 3) { observer.unobserve(entry.target); } } }); };
이렇게 종료 조건을 미리 명시해주면, 무한 스크롤이 정상적으로 동작하게 된다!!