KUKJIN LEE's profile picture

KUKJIN LEE

Posted time

Posted 1 month ago

react-intersection-observer로 React 무한 스크롤 쉽게 구현하기

react-intersection-observer 소개

  • 패키지 개요
    • Intersection Observer API를 React에서 쉽게 활용할 수 있도록 Hook과 컴포넌트 형태로 제공하는 라이브러리입니다.
    • useInView Hook이나 <InView> 컴포넌트를 사용하면 DOM 요소가 뷰포트에 들어오거나 나가는 시점을 쉽게 감지할 수 있음.
    • 타입스크립트로 작성되어 있어 타입 안정성 보장.

 

  • 왜 선택했는가?:
    • 성능 최적화: 동일한 Intersection Observer 인스턴스를 재사용해 메모리 및 성능 측면에서 이점 제공.
    • 사용자 경험(UX): 사용자가 콘텐츠를 자연스럽게 탐색할 수 있게 하기 위함

 

react-intersection-observer

기본 사용법 및 코드 예제

useInView Hook 사용법

특정 요소가 뷰포트에 들어왔을 때 상태가 변화하는 모습을 보여줍니다.

import React from "react";
import { useInView } from "react-intersection-observer";

const InfiniteScrollItem = () => {
  const { ref, inView } = useInView({
    threshold: 0,
  });

  return (
    <div ref={ref} style={{ height: "200px", border: "1px solid #ccc", margin: "10px 0" }}>
      {inView ? "화면에 보임" : "숨겨짐"}
    </div>
  );
};

export default InfiniteScrollItem;

다른 방식으로도 구현이 가능합니다.

import React from "react";
import { InView } from "react-intersection-observer";

const InfiniteScrollComponent = () => (
  <InView>
    {({ inView, ref }) => (
      <div ref={ref} style={{ height: "200px", border: "1px solid #ccc", margin: "10px 0" }}>
        {inView ? "화면에 보임" : "숨겨짐"}
      </div>
    )}
  </InView>
);

export default InfiniteScrollComponent;

무한 스크롤 구현 사례

우리에게 가장 중요한 건 무한 스크롤 구현이죠.

리스트 마지막에 ref를 부여하여 스크롤이 해당 영역 진입 시 새로운 데이터를 불러오도록 합니다.

import React, { useState, useEffect } from "react";
import { useInView } from "react-intersection-observer";

const InfiniteScrollList = () => {
  const [items, setItems] = useState(Array.from({ length: 20 }, (_, i) => `Item ${i + 1}`));
  const { ref, inView } = useInView({
    threshold: 0,
  });

  useEffect(() => {
    if (inView) {
      // 스크롤이 마지막 요소에 도달했을 때 새로운 아이템 추가
      setTimeout(() => {
        setItems(prev => [...prev, ...Array.from({ length: 10 }, (_, i) => `Item ${prev.length + i + 1}`)]);
      }, 1000);
    }
  }, [inView]);

  return (
    <div>
      {items.map((item, index) => (
        <div key={index} style={{ padding: "20px", borderBottom: "1px solid #eee" }}>
          {item}
        </div>
      ))}
      {/* 마지막 요소에 ref를 부여 */}
      <div ref={ref} style={{ height: "50px", textAlign: "center", padding: "20px" }}>
        Loading...
      </div>
    </div>
  );
};

export default InfiniteScrollList;

쉽게 무한 스크롤을 구현할 수 있는 라이브러리입니다.

간결하지만, 추가적인 옵션을 구현할 때 기능이 제한적일 수 있습니다. 즉 무한 스크롤 한정이다~!

New Tech Posts