IntersectionObserver 를 활용한 react infinite scroll

이무헌·2022년 11월 16일
0

react

목록 보기
10/19

클론코딩의 필수 덕목 infinite scroll이다.
원리를 설명하자면, react에서 dom을 접근할 수 있는 거의 유일한 요소인 ref를 활용하여 해당 element가 화면에 보인다면 특정 콜백함수를 실행시킴으로서 새로운 데이터를 fetch하는 것이다. 바로 코드로 넘어가자

  const [target, setTarget] = useState<any>(null);


  useEffect(() => {
    const observer = new IntersectionObserver(callBackFunction, options);
    const currentTarget = target;
    if (currentTarget) observer.observe(currentTarget);

    return return () => observer && observer.disconnect();
  }, [target, options]);

저게 무슨 코드인가요? 컴포넌트가 mount될 때 observer 를 IntersectionObserver의 새로운 객체로 생성한다.
매개변수는 두개인데 callBackFunction은 요약하자면 특정 element(인스타라고 가정한다면 맨 마지막 리스트 되시겠다.)가 화면에 보이면 실행시킬 콜백 함수 이고 option은 얼마만큼 보여야하고, 얼마만큼의 노출이 있어야지 화면에 표시 됐다고 인식할래? 를 정하는 파라미터이다. 노출시켜야할 element는 다음과 같다.

                   <div ref={setTarget}></div>

target이 null이 아닐경우, observer는 observe 프로토타입 함수를 이용하여 해당 타겟의 엘리먼트를 관찰하기 시작한다. 아까 언급했듯이 얼마나 노출됐을 때 관찰됐다고 정의할래? options는 다음과 같다.

 const options = useMemo(() => {
    return {
      root: null,
      rootMargin: "0px",
      threshold: 0.5,
    };
  }, []);

변하지 않으므로 useMemo로 한번만 생성시켜 주자

우리가 알아야 할 것은 threshold인데, 0.5는 50프로가 노출됐을 때 관찰됐다고 취급해주세요 라는 의미이다. 그럼 관찰 됐을 때 실행할 함수는?

const callBackFunction = async (entries: any, observer: any) => {
    const [entry] = entries;

    if (entry.isIntersecting) {
      observer.unobserve(entry.target);
      await new Promise<void>((resolve, reject) => {
        return setTimeout(resolve, 2000);
      });
      setPage(page + 1);
      observer.observe(entry.target);
    }
  };

관찰된 순간에 수백번의 함수실행을 막기 위해 2초의 텀을 두었다. 관찰을 중지한 후 페이지를 +1 한 후 다시 새로운 타겟을 관찰한다,

정리해보자.

1.currentTarget 이 null이 아니라면 해당 element를 관찰( observer.observe(currentTarget);)
2.관찰 됐다면 callBackFunction 실행! (추후에 외부에서 데이터를 받아와 추가하면 되겠다.)
3.cleanUp function ( return () => {
if (currentTarget) observer.unobserve(currentTarget);
};) 으로 unmount된다면 관찰을 포기시켜준다.

끗!

profile
개발당시에 직면한 이슈를 정리하는 곳

0개의 댓글