React/디벨킷 (리액트 프로젝트)

[React] - Intersection Observer로 무한스크롤 (1)

위르겐 2022. 12. 10. 23:47

 

프로젝트 내에서 무한스크롤을 구현하기 위해

Intersection Observer API를 사용했으며

여러 곳에서 재사용하기 위해

커스텀훅으로 만들어 놓았다.

 

동작원리를

간단하게 설명하면

 

먼저 observer(관찰자)를 생성해준다

 

사용자가 브라우저에서 스크롤을 내려

observer가 타겟을 보게끔 해주면 

추가적인 데이터를 받아와 

화면에 렌더링 하는방식이다.

 

 

현재 프로젝트에서

Intersection Observer를 세개의 컴포넌트에서 사용하고 있기 때문에

커스텀 훅으로 만들었으며 

그 훅을 먼저 설명하겠다.

 

 

import { useEffect, useRef } from 'react';

export default function useObserver(options) {
  const { fetcher, dependency, isLoading } = options;
  const target = useRef(null);

  useEffect(() => {
    let observer;
    if (target.current && !isLoading) {
      observer = new IntersectionObserver(onIntersect);
      observer.observe(target.current);
    }
    return () => observer && observer.disconnect();
  }, [dependency]);

  const onIntersect = (entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        setTimeout(() => {
          fetcher();
        }, 300);
      }
    });
  };

  return { target };
}

 

 

useObserver훅을 만들었으며

파라미터로 각각 

fetcher, dependency, isLoading을 받아오고 있다.

또한 useRef를 통해 타겟으로 사용할 element를 지정해준다.

 

 

 

 

이 훅을 사용하고 있는 컴포넌트가 렌더링 된 후

훅 내에서 useEffect가 실행된다.

 

  useEffect(() => {
    let observer;
    if (target.current && !isLoading) {
      observer = new IntersectionObserver(onIntersect);
      observer.observe(target.current);
    }
    return () => observer && observer.disconnect();
  }, [dependency]);

observer를 선언해준 후

useRef로 지정해뒀던 태그가 존재하고 동시에 로딩중이 아닐 때 

observer는 IntersectionObserver 생성자가 되며 onIntersect함수가 실행된다.

이 때 observer.observe로 해당 ref 타겟을 관찰하기 시작한다.

컴포넌트가 언마운트되면 이 observer는 disconnect된다.

 

      observer = new IntersectionObserver(onIntersect);

 

이곳에 콜백으로 들어가는 onIntersect 함수는

아래와 같은데

  const onIntersect = (entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        setTimeout(() => {
          fetcher();
        }, 300);
      }
    });
  };

 

 

observer가 타겟을 관찰할 때

추가 데이터를 가져오는 함수인 

fetcher()를 실행시키는 역할을 한다.

entries는 IntersectionObserverEntry 인스턴스를 담은 배열이며

콜백함수의 첫 번째 파라미터로 전달된다.

 

위 함수에서는 타겟이 관찰될 때

0.3초 후에 fetcher()함수가 실행되어 바로 추가데이터를 렌더링 해준다.

 

 

 

여기까지 로직을 설명하였고

다음 글에서는 어떻게 사용할 수 있을 지 알아보자!

반응형