[React] GraphQL + React + fetchMore infinite Scroll 페이지네이션

2020. 12. 26. 15:10JavaScript/React

step1 Query 컴포넌트 작성

  <Query
              query={LIST_STORES_QUERY}
              variables={{
                page: 0,
              }}
            >

step2) Botton Scroll End를 감지하는 함수 선언

  const handleOnScroll = () => {
    var scrollTop =
      (document.documentElement && document.documentElement.scrollTop) ||
      document.body.scrollTop;
    var scrollHeight =
      (document.documentElement && document.documentElement.scrollHeight) ||
      document.body.scrollHeight;
    var clientHeight =
      document.documentElement.clientHeight || window.innerHeight;
    var scrolledToBottom = Math.ceil(scrollTop + clientHeight) >= scrollHeight;
    if (scrolledToBottom) {
      onLoadMore();
    }
  };

step3 ) view mount 생명주기에 step2에서 선언했던 스크롤 감지 함수 리스너 등록

  useEffect(() => {
    window.addEventListener("scroll", handleOnScroll);
    return () => window.removeEventListener("scroll", handleOnScroll);
  }, []);
//return의 뒷정리 함수를 사용하여 페이지에서 벗어날때 리스너를 삭제해준다(메모리 누수 방지)

step4) fetchMore함수 작성

  • 여기서 주의할점은 객체 merge를 잘 해주어야한다
  • 객체 안에 고유 값인 __typename, total등의 속성을 없애고 merge하다보면 map함수가 제대로 작동하지 않는다.
  • 객체 복사, merge공부를 제대로 하고 updateQuery를 작성하자
      onLoadMore = () => {
                  fetchMore({
                    variables: {
                      page: data.adminUser.result.length,
                    },
                    updateQuery: (prev, { fetchMoreResult }) => {
                      if (!fetchMoreResult) return prev;
                      const newData = {
                        ...prev,
                        adminUser: {
                          ...prev.adminUser,
                          result: [
                            ...prev.adminUser.result,
                            ...fetchMoreResult.adminUser.result,
                          ],
                        },
                      };
                      return newData;
                    },
                  });
                };