https://simian114.gitbook.io/blog/undefined/react/intersectionobserverapi

 

IntersectionObserverAPI로 무한스크롤 구현 - 공부방

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

simian114.gitbook.io

위 게시물의 내용을 보고 이해한 내용을 담았다.

 

필요한 개념:

 - useState로 반환된 setter 함수랑 useref랑 연동해서 쓰는 법

 - 리액트 state를 스냅샷으로 관리하는 개념, 이를 통해서 useEffect에서 언마운트 될 때 observe 대상 변경하는 것

 

import { useEffect, useRef, useState } from 'react';
import 'intersection-observer';

export const useIntersectionObserver = (callback) => {
  const [observationTarget, setObservationTarget] = useState(null);
  const observer = useRef(
    new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (!entry.isIntersecting) return;
        callback();
      })},
      { threshold: 1 }
    )
  );

  useEffect(() => {
    const currentObserver = observer.current;
    if (observationTarget) {
      currentObserver.observe(observationTarget);
    }
    return () => {
      if (observationTarget) {
        currentObserver.unobserve(observationTarget);
      }
    };
  }, [observationTarget]);

  return setObservationTarget;
};

 

커스텀 훅을 만드는 코드이다.

  1. useState를 통해 observationTarget과 setObservationTarget을 생성한다.
  2. observer는 리랜더링에도 새로 생성되지 않도록, 성능향상을 위해 useRef로 만들어준다. 교차하고 있다면 콜백함수를 실행시켜준다.
  3. observationTarget이 변경될 때마다 useEffect를 통해 새로운 타겟을 구독한다.
  4. useEffect가 언마운트 될 때, 기존의 구독을 풀어준다.

사용은 이런식으로 한다.

const setObservationTarget = useIntersectionObserver(fetchMoreComments);

function CardList() {
  ...
    return (
    <StyledCardListContainer>
      {comments.map((comment) => (
        <Card key={comment.id} comment={comment} />
      ))}
      {isLoading && <div>Loading...</div>}
      {!isLoading && <div ref={setObservationTarget}></div>}
    </StyledCardListContainer>
  );

 

  1. setObservationTarget이 리턴되었다.
  2. ref에 set함수를 넣어준다, observationTarget은 해당 ref를 참조한다.
  3. 해당 div에 해당하는 값이 setObservationTarget()안에 들어가서 훅이 실행된다.
  4. ObsercationTarget의 값이 변하므로, useEffect도 실행된다.
  5. currentTarget에 해당 div가 들어오면서,observer가 observe 할 수 있다.

+ Recent posts