[React-Query] Section 03

은채·2022년 9월 21일
0
post-thumbnail

Infinite Scroll

  • 사용자가 스크롤 할 때마다 새로운 데이터를 가져온다
  • 모든 데이터를 한 번에 가져오는 것보다 효율적
    ex. 트위터
  • 언제 새로운 데이터를 가져오는가?
    • 사용자가 버튼을 눌렀을 때
    • 페이지의 특정 지점을 스크롤 했을 때

useInfiniteQuery

  • 페이지네이션과는 다른 api 사용
  • 페이지네이션
    • 현재 페이지를 컴포넌트 상태에서 추적
    • 사용자가 새 페이지를 열기 위해 버튼을 클릭했을 때, 업데이트 된 상태가 쿼리 키를 업데이트하고 쿼리 키가 데이터를 업데이트 하는 방식
  • useInfiniteQuery
    • 다음 쿼리가 무엇인지 추적함
    • 다음 쿼리가 데이터의 일부로 반환
    • 사용할 api에서는 result 라는 데이터 배열을 가진 객체를 프로퍼티로 갖는다.
    • 또한, api에서는 다음에 사용할 쿼리와 이전 쿼리, 총 페이지 수를 알려준다.

useQuery vs useInfiniteQuery

  1. 반환된 데이터의 형태가 다르다.
  • useQuery : 단순히 쿼리 함수에서 반환되는 데이터 형태
  • useInfiniteQuery : 두 개의 프로퍼티를 갖는다
    1) pages : 배열 형태
    : 페이지에 있는 각 요소가 useQuery에서의 데이터와 같은 형태
    2) pageParams
    : 각 페이지의 매개변수 기록 (많이 사용되는 편은 아니다!)
    : 모든 쿼리는 페이지 배열에 고유한 요소를 가지고 있고 그 요소는 해당 쿼리에 대한 데이터에 해당한다 => 페이지가 진행되며 쿼리도 변경됨
    : pageParams는 검색된 쿼리의 키를 추적
  1. 구문이 다르다.
  • pageParams : 쿼리 함수에 전달되는 매게 변수
useInfiniteQuert("sw-people(쿼리 키)", ({ pageParam = 
defalutUrl (첫번째로 정의한 Url을 기본값으로 사용) }) => fetchUrl(pageParma)
  • React-Query가 pageParam의 현재 값을 유지
  • 컴포넌트 상태 값의 일부 XX
  • useInfiniteQuery에 옵션을 사용
    • getNextPageParam : (lastPage, allPages) >> 다음페이지로
      • 마지막 페이지의 데이터, 모든 데이터에서 다음 페이지의 url 획득

      • pageParam을 업데이트 (next 프로퍼티 사용)

  1. 반환 객체의 특수한 프로퍼티
  • fetchNextPage : 사용자가 더 많은 데이터를 요청할 때 호출
    ex. 더 많은 데이터가 필요하여 버튼을 누를 때 / 스크린에서 데이터가 소진되는 지점을 누를 때
  • hasNextPage : getNextPageParam의 반환 값을 기반으로 하는 함수
    • 이 프로퍼티를 useInfiniteQuery에 전달하여 마지막 쿼리의 데이터를 어떻게 사용할 것인지 지정
    • undefined 인 경우 => 더 이상 데이터 없음
    • useInfiniteQuery에서 반환 객체와 함께 반환 된 경우 hasNextPage는 거짓
  • isFetchingNextPage : 다음 페이지를 가져오는 지 ? 아니면 일반적인 페칭인지 구별 가능

Flow

  1. 컴포넌트가 마운트 되다
  2. 이 시점에서 useInfiniteScroll이 반환된 객체의 data : undefined
    프로퍼티가 정의되어 있지 않다. (쿼리를 만들지 않았기 때문에)
  3. useInfiniteScroll이 쿼리 함수를 사용하여 1페이지를 가져온다

  1. 쿼리 함수는 useInfiniteScroll의 첫 번째 인수
    그리고 pageParam을 인수로 받음
    첫 pageParam은 우리가 기본 값으로 정의한 것이 지정

  1. pageParam을 사용하여 첫 번째 페이지를 가져오고 반환 객체 데이터의 페이지 프로퍼티를 설정한다.
    => 인덱스가 0인 배열의 첫 번째 요소 설정
    => { .. } 쿼리 함수가 반환 하는 값

  2. 데이터가 반환된 후 react-query가 getNextPageParam (useInfiniteScroll의 옵션)을 실행
    => lastPage, allPages를 사용해서 받아온 내용을 바탕으로,
    pageParam을 업데이트 => 다음페이지 링크가 업데이트 된다

  1. 다음 페이지?
    hasNextPage 값을 정의하는 방식 => pageParam이 정의되어있는가 여부

  2. 다음페이가 있는 상태에서
    1) 다음페이지 버튼 누르기 2) 스크롤 하기 등을 통해 fetchNextPage 함수를 호출 할 때, useQuery가 useInfiniteScroll을 실행한다

  3. 이를 사용해서 또 다음 요소를 업데이트하거나, 데이터의 프로퍼티인 페이지 배열에 다음 요소를 추가

  4. 새 데이터를 가지고 getNextPageParam 실행하여 NextPageParam을 설정

  5. 더이상 페이지가 없다면?
    pageParam : undefined

  6. hasNextPage 도 거짓이 된다 => 작업 완료, 더이상 데이터 없음

사용하기

React-Infinite-Scroller

  • loadMore = {fetchNextPage}
    : 데이터가 더 필요할 때 불러오는 함수

  • hasMore = {hasNextPage}
    : hasNextPage는 useInfiniteQuery 에서 반환된 내용을 해체하여 사용

  • 무한 스크롤 컴포넌트 부분

  • pages 배열 -> result 배열 로 넘어가기

  • 현재 사용하고 있는 api의 구조

  • console.log 확인해보면?

  • 데이터가 정의되지 않는 오류가 발생함

페칭과 에러

  • useQuery 처럼 isLoading 사용하기 => 캐시된 데이터가 없을 때의 데이터 정의
  • isError, error => 에러 발생 시 화면 정의

  • 더이상 에러가 발생하지 않는다 ㅎㅎ
  • 그런데 정해진 위치에 도달해서 새로 데이터를 가져 올 때 사용자에게 피드백을 주지 않는다 => 데이터 수집하는 피드백을 줘보자.

isLoading 을 isFetching 으로 바꾼다면?

  • 최초 데이터 패칭은 잘 되지만, 새로운 페이지가 열릴 경우 스크롤이 위로 돌아간다

  • 왜? 데이터는 더 있지만 새로운 페이지가 열릴 때마다 바로 조기 retrun 이 되어버리기 때문이다.

isLoading과 isFetching 을 함께 사용하기

  • loading 중 일 때,
  • isFetching 중 일때를 각각 지정해준다.

  • 스크롤도 끊기지 않고, 데이터를 새로 가져오는 것도 보인다.

양방향 스크롤 (Bi-directional Scrolling)

  • 데이터의 중간부터 시작할 때 유용 (시작점 + 이전 데이터 + 이후 데이터)
  • next 메서드처럼 previous 메서드도 존재
  • 둘 다 수행하면 양방향 스크롤이 가능함
profile
반반무마니

0개의 댓글