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

Intersection Observer API 이용하여 무한스크롤 구현하기 / 교차 전에 콜백함수가 실행되는 오류 해결

by growingTangerine 2023. 5. 29.

1. target 이 undefined 로 뜨는 문제 -> useRef / target.current / if 조건문으로 해결

2. 콜백함수가 계속 호출되는 문제 (Chat GPT에게 질문해서 해결!)

-> target element가 처음 렌더링 되었을 때, 콜백이 바로 실행되기 떄문. 스크롤이 실제 요소 위치에 도달하기 전에 이미 콜백이 실행되고 있음. 

 

해결책) 

1. 콜백 함수 내부에서 추가적인 검사를 수행하여 실제로 스크롤이 페이지 하단에 도달했는지 확인하기. 

let observer = new IntersectionObserver(
  entries => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        setPage(page + 1);
        console.log(page);
      }
    });
  },
  { root: null, threshold: 1.0 }
);

entry.isIntersecting -> IntersectionObserverEntry의 속성으로, 대상 요소가 관측자의 교차 영역에 들어있는지를 확인함. 

 

2. useEffect 훅을 사용하여 IntersectionObserver를 설정하고, target이 변경될 때마다 observer를 재설정하도록 하면 문제를 해결할 수 있음.

let target = useRef();
let [page, setPage] = useState(0);

useEffect(() => {
  let observer = new IntersectionObserver(
    entries => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          setPage(page + 1);
          console.log(page);
        }
      });
    },
    { root: null, threshold: 1.0 }
  );

  if (target.current) {
    observer.observe(target.current);
  }

  // cleanup 함수에서 관찰을 중지
  return () => {
    if (target.current) {
      observer.unobserve(target.current);
    }
  };
}, [page, target]); // page 또는 target 변경시 useEffect 재실행

-> useEffect 훅이 page 또는 target의 상태 변경시마다 재실행되어, target에 대한 observer 관찰을 새로 설정하게 됨. 이렇게 하면 콜백이 스크롤이 실제 요소 위치에 도달했을 때만 실행되도록 보장할 수 있음. 

이렇게 isIntersecting과 useEffect를 추가해주니, div 태그가 뷰포트에서 관측되는 동안에만 콜백함수가 호출되었다. 

 

+ entries[0]을 콘솔에 찍어보았다. 

 

해당 DOM에 대한 정보를 보여준다. 뷰포트에서 div 태그가 없어졌을 때에는, intersectionRatio: 0 / isIntersecting: false로 바뀐다!