For the complete documentation index, see llms.txt. This page is also available as Markdown.

IntersectionObserverAPI로 무한스크롤 구현

Intersection Observer는 어떤 문제들을 해결하기 위해 등장했을까?

기존에는 스크롤바에 기반해서 무한스크롤을 구현했다. 그렇게 하기 위해서는 아래처럼 박스가 되는 곳에 스크롤에 대한 이벤트를 걸어야 했다.

<StyledCardListContainer onScroll={handleScroll}>
  {comments.map((comment) => (
    <Card key={comment.id} comment={comment} />
  ))}
</StyledCardListContainer>

이렇게 하게 됨으로써 생기는 문제가 있다. 바로 스크롤이 될 때 마다 handleScroll 이 동작하는 것이다. handleScroll 메서드는 결국 자바스크립트의 메인엔진에서 실행이 되어야하므로 많은 부하가 걸리게 된다.

이런 문제를 해결해 줄 수 있는게 바로 intersection-observer API 이다.

그렇다면 어떻게 위의 문제를 해결해줄 수 있을까?

간단하다. intersection observer APIWeb API 이기 때문이다!! 즉, 스크롤이 일어날 때 마다 자바스크립트의 코드를 곧잘 돌려야하는 이전과는 달리 해당 API 를 사용하면 자바스크립트 엔진과는 상관없이 브라우저단에서만 무한스크롤 로직을 검사하고, 조건을 통과하는 경우에는 자바스크립트의 코드로 데이터를 불러오면 되는것!

Intersection Observer에 대해 알아보자.

intersection observer의 흐름을 알아보자

intersection observer 는 무한스크롤에만 사용되는건 아니다...

API는 크게 관찰자(observer)관찰 대상(entry), 옵션(조건) 그리고 콜백함수(로직) 이 존재한다.

  1. 관찰자를 생성한다.

  2. 관찰 대상을 생성한다.

  3. 관찰자관찰 대상을 관찰한다

  4. 관찰 대상조건을 만족하는 상태에 놓이게 된다면 콜백 함수를 실행한다.

코드로 알아보자

관찰자의 생성(관찰자, 옵션, 콜백함수...)

https://developer.mozilla.org/ko/docs/Web/API/IntersectionObserver/IntersectionObserver

https://developer.mozilla.org/ko/docs/Web/API/IntersectionObserver

  1. callback은 콜백함수다 즉 조건이 만족하면 실행할 함수

  2. options 는 각종 조건들을 넣을 수 있다. 자세한건 MDN 사이트에서 보자.

    • 가장 중요한점은 threshold 다. 관찰 대상이 화면에 어느정도 보이면 조건이 참인지를 결정하는 요소다. 매우 중요하다.

  3. 리턴값(observer) 은 관찰자 가 된다. 자세한 사용법은 링크를 참고하자.

    1. observe

      • 관찰 대상을 지정할 수 있다. 관찰 대상은 하나 이상일 수 있다!!, 다만 그 조건은 변하지 않는다.

    2. unobserve

      • 관찰 대상에 대한 관찰을 중지한다.

관측 대상의 생성

이제 target 이 특정 조건을 만족하게 되는 경우 callback 메서드를 호출한다.!

조건이 만족하게 되면 어떤 모습으로 callback이 실행될까?

callback을 제대로 사용하기 위해서는 intersection-observer API 제시하는 방향으로 만들어야한다.

IntersectionObserver 생성하기

IntersectionObserverEntry

해당 링크 에서 스크롤을 내려 Targeting an element to be observed 를 보자. 여기를 보면 callback 을 어떻게 정의해야하는지를 알려준다.

즉 조건을 만족하게 될 경우 Intersection-observer API콜백함수 에게 entries 를 주게 된다. 그리고 이 entries관찰 대상의 리스트다. 따라서 사용자는 이 관찰 대상의 리스트 에서 지금 조건을 만족한 관찰 대상 을 찾고 우리가 원하는 로직을 실행해주면 되늑 것이다!!!!

준비는 끝났다. 리액트에서 실제 코딩을 해보자

코딩을 하기 전에 생각할것

  1. Intersection Observer조건으로 무엇을 넣어줄 것인가.

    • 스크롤바가 바닥에 닿으면 새로운 데이터를 불러오게 만들자.

  2. 관찰 대상 은 무엇인가?

    • 관찰 대상은 리스트의 맨 아래에 비어있는 html 태그로 선언한다.

  3. 어떤 로직(콜백함수) 를 넣어줄 것인가?

    • 새로운 데이터를 불러오는 로직을 넣는다.

만드는 순서

관찰 대상을 만들자

리스트의 맨 아래에 관찰 대상 을 만든다. 여기서 중요한건 ref={setObservationTarget} 다.

관찰자 를 만들자

관찰 대상이 하나이므로 콜백함수 의 인자로 들어오는 entries 에서 구조화할당? 을 이용해 entry 하나만을 가져온다. 그리고 이 entry 의 속성인 isIntersecting 를 이용해 조건을 검사하고, 콜백함수 를 실행한다.

자, 이렇게 관찰자, 관찰 대상, 조건, 콜백함수 를 다 만들었으니 끝난걸까? 아니다. 지금 이대로 실행하면 절대 원하는 결과를 얻지 못한다. 왜? 관찰 대상 은 새로운 데이터를 가져올 때 마다 변해야하기 때문!!!

관찰 대상을 수시로 변경해주자

리액트에서 무언가 변하고 이에대한 처리를 해줄 때 사용하는 훅이 있다. 바로 useEffect

  1. 스크롤을 내린다.

  2. 관찰 대상을 만나고, 조건을 만족시킨다.

  3. 새로운 데이터를 가져온다.

    • 이 때 stateloadingtrue 이므로 관찰 대상 이 사라진다.

  4. 새로운 데이터를 리스트에 추가한다.

    • loading 이 다시 false 가 되므로 관찰 대상 이 다시 렌더링된다.

  5. 관찰 대상 이 다시 렌더링 됐지만, 3번과 4번의 과정에서 지워지고 새롭게 만들어졌다.

    1. 따라서 지워진 관찰 대상관찰 대상 리스트 에서 제거해줘야하고

    2. 새롭게 관찰 대상을 지정해줘야한다.

이런 로직을 담당할 수 있게 해주는 코드는 아래와 같다.

관련 로직을 커스텀훅으로 만들자

왜 커스텀 훅으로 만들어야하는가? 해당 로직을 따로 분리하면 분명 다른 프로젝트에서 사용할 수 있을거로 보이기 때문!

코드

의문점

  1. useEffect 에서 clean-up 을 꼭 해줘야하는가?

    • 해줘야한다!! 실행상에 문제는 없다. 다만 이전의 타겟이 남아있기 때문에 callback 이 쓸데없이 더 불러와지는 문제가 있다(물론 callback이 실행되도 isIntersecting에서 걸리기 때문에 대부분의 경우 걱정할 필요가 없지만...)

    • clean-upuseEffect 에서 가장 먼저 실행된다. 따라서 현재의 로직을 실행하기 전에, closure로 이전의 데이터가 존재하면 clean-up 해주는 것.

사용법

  1. 무한스크롤 이 필요한 컴포넌트에서 해당 훅으로 setObservationTarget 을 선언한다. 실행할 로직을 인자로 넘겨준다!!

  2. 리스트의 맨 아래에 빈 태그를 만들고 ref 를 연결해주자.

Last updated