정말 쉽다! intersectionobserver 무한스크롤

이준석·2023년 12월 20일
0

React_Study

목록 보기
6/8

최근 웹 디자인에서 페이지네이션과 무한스크롤이라는 두 가지 주요한 컨텐츠 로딩 방식이 있습니다. 각각의 방식은 고유한 장단점을 가지고 있어, 개발자는 여러가지 조건에 따라 어떤 방식을 선택해야 할지 신중한 결정이 필요합니다.

페이지네이션(Pagination)

페이지네이션은 디지털 콘텐츠를 웹사이트의 또 다른 페이지들로 분리하는 방법입니다. 사용자는 페이지 하단에 있는 숫자 형식의 링크를 클릭하여 페이지들을 탐색할 수 있습니다. 페이지네이션된 콘텐츠 일반적으로 몇 가지 공통된 주제 혹은 목적들을 지니고 있습니다.

장점

  • 쉬운 네비게이션 :
    사용자는 페이지 간의 이동이 쉽고 직관적입니다.
  • 더 나은 성능 :
    초기 로딩 속도를 향상시켜 전체적인 사용자 경험을 향상시킵니다.
  • 검색 엔진 최적화 :
    검색 엔진은 페이지를 기반으로 컨텐츠를 쉽게 인덱싱할 수 있습니다.

단점

  • 사용자 경험 저하 :
    페이지 이동이 필요하므로 사용자는 여러 페이지를 거치며 정보를 찾아야 합니다.
  • 인터랙션 감소 :
    페이지 이동 시마다 로딩이 발생하여 사용자 인터랙션이 끊길 수 있습니다.

무한 스크롤(Infinite scroll)

무한 스크롤은 사용자가 페이지 하단에 도달했을 때, 콘텐츠가 계속 로드되는 사용자 경험(UX, User EXperience) 방식입니다. 이는 마치 끝이 없는 단일 페이지에서 끝없는 정보의 흐름을 경험하게 만듭니다.

장점

  • 자연스러운 경험:
    사용자는 스크롤을 통해 자연스럽게 컨텐츠를 불러올 수 있습니다.
  • 사용자 유입 증가:
    계속해서 새로운 컨텐츠가 나타나면서 사용자는 더 오래 애플리케이션에 머무를 가능성이 높아집니다.
  • 인터랙션 연속성:
    페이지 이동 없이 컨텐츠를 불러오므로 사용자 인터랙션이 연속적입니다.

단점:

  • 성능 문제:
    초기 로딩이 느릴 수 있으며, 많은 양의 데이터를 처리할 때 성능 문제가 발생할 수 있습니다.
  • 데이터 관리의 어려움:
    대량의 데이터를 다룰 때 메모리 소비나 성능 문제가 발생할 수 있습니다.
  • 푸터 탐색 어려움:
    페이지의 끝을 명확히 인지하기 어려울 수 있습니다.

React로 간단한 무한스크롤 구현하기

// ... (컴포넌트 및 필요한 라이브러리 import)

const MemoList = ({ user }: { user: string }) => {
  // 상태 및 리프트 상태 선언
  const [memoList, setMemoList] = useState<memo[]>([]);
  const [page, setPage] = useState(0);
  const [loading, setLoading] = useState(false);
  const [showLinkBox, setShowLinkBox] = useState<number | null>();
  const pageEnd = useRef<HTMLDivElement>(null);
  // ... (나머지 코드)

  useEffect(() => {
    fetchMemos(page, setMemoList, setLoading);
  }, [page]);

  useEffect(() => {
    if (loading && pageEnd.current !== null) {
      io.observe(pageEnd.current);
    }
  }, [loading]);

  // ... (나머지 코드)

  return (
    <MemoListBox>
      {/* 메모 리스트 맵핑 */}
      {memoList.map((item, index) => (
        <li key={index}>
          {/* 메모 아이템 렌더링 */}
          {/* ... (메모 아이템 구성 요소) */}
        </li>
      ))}
      {/* 페이지 끝에 도달하면 새로운 페이지를 불러오는 ref */}
      <div ref={pageEnd} />
      {/* 로딩 중이면 로딩 아이콘 표시 */}
      {loading && <LoadingIcon />}
    </MemoListBox>
  );
};

export default MemoList;

fetchMemos 함수는 API에서 메모를 가져오고 memoList에 추가합니다.

const fetchMemos = async (
  page: number,
  setMemoList: React.Dispatch<React.SetStateAction<memo[]>>,
  setLoading: React.Dispatch<React.SetStateAction<boolean>>,
) => {
  setLoading(true);
  const response = await getMemo(page);
  const newList = response.memos;
  setMemoList((prev) => [...prev, ...newList]);
  setLoading(false);
};

observer 함수를 사용하여 Intersection Observer를 생성하고, 페이지의 끝에 도달하면 페이지를 증가시킵니다.

const observer = (setPage: React.Dispatch<React.SetStateAction<number>>) => {
  return new IntersectionObserver(
    (entries) => {
      if (entries[0].isIntersecting) {
        setPage((prev) => ++prev);
      }
    },
    { threshold: 1 }
  );
};

마무리

React를 사용하여 간단한 무한스크롤을 구현하는 방법을 살펴보았습니다. 페이지의 끝에 도달하면 자동으로 새로운 데이터를 불러오는 이 기능은 사용자에게 끊김 없는 경험을 제공하여 웹 애플리케이션의 사용성을 향상시킬 수 있습니다.

0개의 댓글