티스토리 뷰

들어가며

피드 관련 기능을 개발할 때 Infinite-scrolling을 구현해야 할 일이 있었습니다.

구현할 때 react-waypoint를 활용했었는데, 이번 시간에는 구현 원리와 과정을 설명해볼까 합니다.

 

react-waypoint: https://github.com/civiccc/react-waypoint

 

civiccc/react-waypoint

A React component to execute a function whenever you scroll to an element. - civiccc/react-waypoint

github.com

코드

import * as React from 'react';
import {Waypoint} from 'react-waypoint';
import styled from 'styled-components';

interface Props {
  loadMore: () => void;
  threshold?: string;
  hasMore: boolean;
  loader: React.ReactNode | React.ComponentType;
  children: React.ReactNode;
  className?: string;
}

const InfiniteScrollDiv = styled.div`
  padding-top: 35px;
`;

const InfiniteScroll: React.ExoticComponent<Props> = React.memo(({
  loadMore,
  threshold,
  hasMore,
  loader,
  children,
  className
}) => (
  <InfiniteScrollDiv className={className}>
    {children}
    {hasMore && (
      <Waypoint
        onEnter={loadMore}
        bottomOffset={threshold}
      >
        {loader}
      </Waypoint>
    )}
  </InfiniteScrollDiv>
));

export default InfiniteScroll;

 

InfiniteScroll 컴포넌트의 구조는 다음과 같습니다.

 

Props부터 설명을 드리자면,

 

1. loadMore

데이터를 fetch하는 함수입니다.

초기 렌더링 시 데이터를 불러오거나, 스크롤을 내리면서 추가 데이터를 불러와야 할 때 필수로 사용됩니다. 

 

2. threshold (optional)

페이지의 최하단으로부터의 거리입니다.

스크롤이 페이지의 최하단에 닿기 전에 데이터를 미리 불러오고 싶을 때 활용합니다.

만약 threshold를 "200px"라고 설정하면, 스크롤이 페이지 하단에서 200px의 거리에 있을 때 Waypoint 컴포넌트가 onEnter 됐다고 인식합니다.

 

3. hasMore

불러와야 할 데이터가 더 있는지 판단하는 필드입니다.

값이 false라면, 더 이상 추가적인 데이터가 불러와지지 않습니다.

 

4. loader

데이터가 불러와지기 전에 사용자에게 보여지는 ReactNode 혹은 ReactComponent 입니다.

로딩중이라는 것을 사용자에게 보여주기 위해 넘겨주는 필드입니다.

 

5. children

실제로 렌더링될 (사용자의 눈에 보여지는) 요소입니다.

 

6. className (optional)

스타일 수정을 위해 className이라는 필드 역시 받도록 하였습니다.

다만, 필수적으로 필요하진 않기 때문에 threshold와 동일하게 optional로 설정하였습니다.

 

 

이제 실제로 return 되는 JSX 구문을 그림으로 나타내보겠습니다.

 

동작 1

 

아직 데이터 fetch가 이루어지지 않았기 때문에, children은 렌더링 되기 전입니다.

따라서, 사용자에게는 loader가 보여지는데 이는 아래 그림과 같습니다.

 

동작 2

 

Waypoint가 onEnter 됐으므로, props로 받은 loadMore 함수가 실행됩니다.

실행이 완료되고 children이 렌더링되기 전 까지는 loader가 계속 사용자에게 보여지게 되며, 완료될 시에는 아래 그림의 형태를 띄게 됩니다.

 

동작 3

 

이제, 실제 데이터에 따라 렌더링된 요소가 이제 사용자에게 보여집니다.

스크롤을 내리면서 다시 로딩 컴포넌트를 마주쳤을 때, (= Waypoint가 onEnter 됐을 때) 추가 데이터가 fetch되며 결국 Infinite-scrolling이 가능하게 됩니다.

 

실제 예시

눈으로 확인하시면 이해가 빠르실 듯 하여, InfiniteScroll 컴포넌트를 활용한 피드 컴포넌트를 임의로 제작하였습니다.

예시는 아래에서 보여드리는 사진의 모습과 동일하며, 전체적인 코드는

https://github.com/Pewww/waypoint-infinite-scroll

 

Pewww/waypoint-infinite-scroll

Implementation of Infinite-Scrolling by using React-Waypoint. - Pewww/waypoint-infinite-scroll

github.com

에서 확인하실 수 있습니다!

 

첫 렌더링 시

 


로딩중


 

추가적인 렌더링 완료 후

 

 

마치며

설명이 빈약할 수도 있기 때문에 궁금하신 점이나 수정되어야 할 부분들은 모두 코멘트로 달아주시면 감사하겠습니다!

이상, react-waypoint를 활용한 Infinite-scrolling 구현 포스팅이었습니다.

봐주셔서 정말 감사합니다!

'React, Redux...' 카테고리의 다른 글

RTL로 HOC with React-Hooks 테스트 하기  (0) 2020.03.15
Jest를 이용한 Reducer 테스트  (0) 2020.03.09
댓글