/react-query-dive

Primary LanguageHTMLMIT LicenseMIT

1

  • 리액트 쿼리 설치
  • 쿼리 클라이언트 설치
    • 쿼리/서버의 데이터 캐시를 관리하는 클라이언트
  • 자식 컴포넌트에 캐시/클라이언트 구성을 공유할 쿼리 프로바이더 구성
    • 이에 대한 값으로 사용될 쿼리 클라이언트도 필요
  • 서버에서 데이터를 가져오기 위해 useQuery 훅을 사용
    • 서버에서 데이터를 가져오는 훅

2

  • isFetching

    • 비동기 쿼리가 해결되지 않았음을 의미
    • 이 경우 아직 페칭(Fetching)을 완료하지 않았지만 쿼리가 Axios 호출 또는 GraphQL 호출일 수도 있음
  • isLoading

    • isFetching의 하위 집합(isFetching이 참이면서 쿼리에 대해 캐시된 데이터가 없는 상태)
    • 가져오는 상태로 비동기 쿼리가 해결되지 않았음을 의미
    • 데이터를 가져오는 중이며 표시할 캐시 데이터도 없다는 것
    • 추후 페이지네이션을 진행하면 캐시된 데이터가 있을 때, 없을 때를 구분해야 함
    • ReactQuery는 기본값으로 세 번 시도한 뒤 해당 데이터를 가져올 수 없다고 결정함
      • 시도하는 동안엔 로드 중으로 표시되고, 완료된 후에는 오류 상태로 표시됨
  • isError

    • 반환 객체에는 불리언을 반환하면서 쿼리 함수에서 전달하는 오류도 존재

3

  • React-Query-Devtools

    • 개발 중인 모든 쿼리의 상태 표시
    • 최근 실행 시간 표시
    • 쿼리 키로 쿼리 표시
    • 활성, 비활성, 만료 등 모든 쿼리의 상태를 알려줌
  • 개발자 도구에서 데이터가 만료(stale) 상태로 변경

  • 만료 상태란?

    • 만료된 데이터는 오래된 식빵과 비슷함
    • 데이터 리패칭은 만료된 데이터에서만 실행
    • 데이터 리패칭 실행에는 만료된 데이터 외에 여러 트리거가 존재
      • 컴포넌트가 다시 마운트되거나 윈도우가 다시 포커스가 된 경우
      • 단, 만료된 데이터일 경우에만 리패칭이 실행
    • staleTime은 결국 데이터를 허용하는 '최대 나이'라고 할 수 있음
      • 달리 말하면 데이터가 만료되었다고 판단하기 전까지 허용하는 시간이 staleTime임
      • 데이터의 성격에 따라 staleTime은 모두 달라질 수 있음
    • 그럼 왜 staleTime의 기본값은 0인가?
      • 업데이트가 왜 안되죠? 보다 데이터가 어떻게 늘 최신 상태를 유지하나요? 가 훨씬 나은 질문
      • staleTime을 0으로 설정했다는 것은 데이터는 항상 만료이기 때문에 서버에서 다시 가져와야 한다고 가정한다는 뜻
      • 그렇다면 클라이언트에게 만료된 데이터를 제공할 가능성이 줄어듦
  • staleTime과 cacheTime의 차이?

    • 캐시는 나중에 다시 필요할 수도 있는 데이터
      • 특정 쿼리에 대한 활성 useQuery가 없는 경우 해당 데이터는 콜드 스토리지로 이동
      • 구성된 cacheTime이 지나면 캐시 데이터가 만료되며, 기본값은 5분
      • cacheTime이 관찰하는 시간의 양은 특정 쿼리에 대한 useQuery가 활성화된 후 경과한 시간
      • 페이지에 표시되는 컴포넌트가 특정 쿼리에 대해 useQuery를 사용한 시간을 말함
      • 캐시가 만료되면 가비지 컬렉션이 실행되고 클라이언트는 데이터를 사용할 수 없음
      • 데이터가 캐시에 있는 동안에는 패칭할 때 사용 가능
      • 데이터 패칭을 중지하지 않으므로 서버의 최신 데이터로 새로 고침이 가능
      • 단, 계속해서 빈 페이지만 보는 경우가 생길 수 있음
      • 새로운 데이터를 수집하는 동안 약간 오래된 데이터를 표시하는 것이 빈 페이지보다는 나음
      • 빈 페이지를 보여주고 싶거나 만료된 데이터가 위험할 수 있는 앱의 경우 cacheTime을 0으로 설정하면 됨

4

  • 모든 쿼리가 동일한 쿼리 키를 사용하는 경우
    • 어떤 트리거가 있어야만 데이터를 가져옴
      • 컴포넌트를 다시 마운트할 때
      • 윈도우가 다시 포커스 될 때
      • useQuery에서 반환되어 수동으로 리페칭할 때
      • 지정된 간격으로 리페칭을 자동 실행할 때
      • 혹은 Mutation을 생성한 뒤 쿼리를 무효화할 때
    • 클라이언트의 데이터가 서버의 데이터와 불일치할 때 리페칭이 트리거
  • 쿼리는 게시물 ID를 포함하기 때문에 쿼리별로 캐시를 남길 수 있음
    • 동일한 쿼리에 대한 캐시를 공유하지 않아도 됨
    • 즉, 각 쿼리에 대항하는 캐시를 가지고 쿼리에 라벨을 설정하면 됨
    • 바로 문자열이 아니라 배열 형태로 전달하는 것
    • 의존성 배열이 다르다면 완전히 다른 것으로 간주
    • 데이터를 가져올 때 사용하는 쿼리 함수에 있는 값이 쿼리 키에 포함되어야 함

5

  • 프리패칭
    • 데이터를 캐시에 추가하여 구성할 수 있으나, 기본값으로 만료 상태임
    • 데이터를 사용하고자 할 때 만료 상태에서 데이터를 다시 가져옴
    • 데이터를 다시 가져오는 중에는 캐시에 있는 데이터를 이용해 앱에 나타냄
      • 단, 캐시가 만료되지 않았다는 가정 하
      • 가령 사용자가 특정 게시물 페이지에 cacheTime보다 오래 머무를 수 있는데, 다음 액션을 취할 캐시가 만료되어 로딩 인디케이터가 나타날 것
    • 이렇게 추후 사용자가 사용할 법한 모든 데이터에 프리패칭을 사용함
      • 페이지네이션 뿐만 아니라 다수의 사용자가 웹 사이트 방문 시 통계적으로 특정 탭을 누를 확률이 높다면 해당 데이터를 미리 가져오는 것이 맞음

6

  • Mutation
    • 서버에 데이터를 업데이트하도록 서버에 네트워크 호출
    • 긍정적 업데이트 : 서버 호출에서 모든 내용이 잘 진행될 것으로 간주하는 것으로 사실이 아니라면 롤백을 진행
    • 변이 호출을 실행할 때 서버에서 받는 데이터를 취하고 업데이트된 해당 데이터로 React Query 캐시를 업데이트
    • 관련 쿼리 무효화 : 서버에서 리페치를 개시하여 클라이언트에 있는 데이터를 서버의 데이터와 최신 상태로 유지
  • useMutation은 일부 예외를 제외하고 useQuery와 상당히 유사
    • mutate 함수를 반환하는데 이 mutate 함수는 변경 사항을 토대로 서버를 호출할 때 사용
    • 데이터를 저장하지 않으므로 쿼리 키는 필요하지 않음
    • isLoading은 존재하나 isFetching은 없음
    • 캐시된 항목이 없으므로 isFetching은 성립하지 않음
    • 변이에 관련된 캐시는 존재하지 않고 재시도 또한 기본값으로 존재하지 않음
      • useQuery는 기본값으로 3회 재시도
      • useMutation도 자동 재시도를 적용하고 싶다면 설정할 순 있음
  • 변이의 주기를 다룰 수 있음
    • 반환 객체에 변이 속성을 실행하여 변이 호출 조절
    • 쿼리에서 진행한 것과 유사한 방식으로 주기 처리 가능

7 기초 요약

  1. 패키지 설치
  2. QueryClient를 생성해서 QueryProvider에 추가
    • 모든 자식 컴포넌트가 캐시와 훅을 사용할 수 있음
  3. useQuery, useQuery
    • 데이터를 서버에서 가져오거나 최신 상태인지 확인 가능
    • 반환 객체에는 isLoading, isFetching 그리고 Error가 존재
    • 특정 쿼리의 상태를 사용자에게 알려줄 때 사용
    • staleTime : 윈도우가 다시 포커스될 때와 같은 특정 트리거에서 쿼리 데이터를 다시 가져올지를 결정, 즉 데이터가 사용 가능한 상태로 유지되는 시간을 말함
    • cacheTime : 데이터가 비활성화된 이후 남아 있는 시간으로 캐시된 데이터는 쿼리를 다시 실행했을 때 사용, 즉 데이터가 최신 상태인지 서버에서 확인하는 동안 자리 표시자로 사용자에게 보여짐
    • 쿼리 키 : 디펜던시 배열 혹은 문자열로 관리되며 쿼리 키가 변경됐을 때 useQuery hook은 쿼리를 반복, 따라서 데이터 함수가 바뀌면 쿼리 키도 바뀌거나 데이터를 변경해야 하는 경우 다시 실행될 수 있음
  4. Pagination
    • 페이지를 넘기려면 컴포넌트에서 상태를 어떻게 유지해야 하는가
    • 서버에서 최신인지 확인하는 동안 캐시된 데이터가 보여도록 추가 페이지를 프리페칭하기
  5. useMutation
    • 서버 사이드 이펙트 수행에 사용

8

  • 무한 스크롤
    • 엄청난 양의 데이터를 가져올 때 유용
    • 사용자가 스크롤 할 때마다 새로운 데이터를 가져옴
    • 한 번에 모두 가져오는 것보다 훨씬 효율적
      • 사용자가 버튼을 클릭해서 새로운 데이터를 요청하거나
      • 페이지의 특정 지점을 스크롤 했을 때 새 데이터를 가져오게 하는 것
    • useInfiniteQuery를 사용
      • useInfiniteQuery는 다음 쿼리가 뭘지 추척
      • 다음 쿼리가 데이터의 일부로 반환