[React-Query] React Query 공식 문서 간단 정리

쏘소·2022년 9월 28일
0

Tanstack-Query

목록 보기
1/1

React Query란

보통 서버 state(ajax를 통해 서버에서 가져오는 데이터)가 있고 클라이언트 state가 있는데 데이터 fetching 해서 불러오는 데이터는 서버 state로 관리하는 게 좋다.

React Query의 존재를 알기 전엔 서버에서 가져온 데이터를 internal state 관리를 위한 useState, context api 를 사용하거나, redux, recoil 등의 상태관리 툴을 사용하여 저장하고 가공하여 react 내부에서 사용해주었었다.

하지만, 서버 state는 주로 비동기적으로 다루게 되고, 클라이언트 state는 주로 동기적으로 다루게 되므로 따로 관리해주는 것이 좋다.

React Query는 이를 쉽게 할 수 있게 도와준다.

stale queries가 자동으로 refetch 되는 조건

stale queries가 자동으로 refetch 되는 조건은 다음과 같다.

  • New instances of the query mount - 새 query가 mount 될 때
  • The window is refocused - 윈도우 화면을 focus 하였을 때(refetchOnWindowFocus와 같은 옵션을 줘서 refetch되지 않도록 해줄 수 있다. 공식문서)
  • The network is reconnected. - 네트워크가 재연결 되었을 때
  • The query is optionally configured with a refetch interval. - cacheTime이 지나 refetch가 될 때

staleTime과 cacheTime의 차이

staleTime

staleTime은 data 가 fresh -> stale 로 가는 데 걸리는 시간을 말하는 것이다. Data가 fresh 에 있는 동안은 데이터 fetch가 되지 않는다.(query가 unmount 되었다가 mount되어도.)
fresh 이면, 캐시에 저장된 data 를 그대로 보여준다.

cacheTime

cacheTime은 data 가 inactive 상태가 시작된 서부터 cache 유지 시간을 말하는 것이고, cacheTime 이 지나기 이전에 fetch 가 되면 데이터 fetch가 이루어진다. 데이터 fetch가 이루어지는 동안 캐싱된 previousData를 띄워줄 수가 있다.
staleTime 과는 관계없이 inactive 상태가 시작된 기준이다.

react-query 특징

쿼리 결과는 기본적으로 구조적으로 공유되어 데이터가 실제로 변경되었는지 여부를 감지하고, 그렇지 않은 경우 데이터 참조는 변경되지 않은 상태로 유지되어 useMemo 및 useCallback과 관련하여 값 안정화에 더 도움이 된다.

isLoading vs isFetching

isLoading

캐싱된 Data가 없을 때 첫 fetching 되는 로딩 상태

isFetching

캐싱된 Data가 있는 경우 reFetching 될 때의 로딩 상태

status vs fetchStatus

const result = useQuery(['todos'], fetchTodoList)

status

위의 result object는 크게 세 가지 status 를 가진다.

isLoading or status === 'loading' - The query has no data yet
isError or status === 'error' - The query encountered an error
isSuccess or status === 'success' - The query was successful and data is available

fetchStatus

위의 result object에는 세 가지의 fetchStatus 를 가진다.

fetchStatus === 'fetching' - The query is currently fetching.
fetchStatus === 'paused' - The query wanted to fetch, but it is paused. Read more about this in the Network Mode guide.
fetchStatus === 'idle' - The query is not doing anything at the moment.

status 와 fetchStatus 의 차이점은 무엇일까? 왜 두 가지 state가 있는 것일까?

상태는 success status 임과 동시에 idle fetchStatusfetching fetchStatus 가 될 수 있다. Fetching fetchStatus인 경우엔 백그라운드에서 refetch가 일어나고 있을 경우를 얘기한다.
즉, success status는 이미 data fetch가 성공적으로 이루어진 경우에 query가 data를 가지고 있을 때를 얘기하므로, data 를 가지고 있는 상태에서 뒤에서는 새로운 refetching이 이루어지고 있는 것 일 수 있는 것이다.

Query가 mount 되었지만 data 가 없는 경우는 loading status거나 fetching fetchStatus 가 대부분이다. 하지만 네트워크 연결 오류로 인한paused fetchStatus 일 수도 있다.

즉, status는 data 정보를 가지고 있는 지 여부에 따른 상태고, fetchStatus는 queryFunction 이 실행되고 있는 지에 따른 상태를 말한다고 할 수 있다.

즉, 위에서 설명한 isFetching 의 경우도 status 는 loading일지라도 background에서 fetching 중일 경우 띄워줄 수 있는 것이다.

Query Keys

설정하는 쿼리 키에 따라 React Query는 query 캐싱을 다루게 된다.

useQuery(['todos'], ...)

쿼리 키는 위와 같이 배열로 나타내야 한다.

useQuery(['todos', { status, page }], ...)

위와 같이 배열이 아닌 객체의 형태로 key를 주게 되면 queries 는 일치하는 것으로 여겨지게 된다.

function Todos({ todoId }) {
  const result = useQuery(['todos', todoId], () => fetchTodoById(todoId))
}

query 함수가 변수에 의존하고 있으면, query key에 포함 시켜라

Disabling/Pausing Queries

쿼리가 자동으로 불러와지는 것을 disable 시키기 위해서는 enable 을 false 로 설정하면 된다.
enable: false 일 경우,

  • 캐싱된 데이터가 있는 경우 => status === 'success'isSuccess 상태에서 query 시작
  • 캐싱된 데이터가 없는 경우 => status === 'loading' 그리고 fetching === idle 상태에서 query 시작
  • 쿼리가 자동으로 fetch, refetch 되지 않음
  • refetch를 하게 하는 invalidateQueries 와 refetchQueries 호출을 무시

lazy queries

쿼리가 생성될 때 함께 호출이 되는 것을 막기 위해서 lazy queies 를 사용할 수 있다. 원하는 때에 호출이 되게끔 하게하기 위해서 다음과 같이 사용해줄 수 있다.

const { data } = useQuery(
    ['todos', filter],
    () => fetchTodos(filter),
    {
      // ⬇️ disabled as long as the filter is empty
      enabled: !!filter
    }
  )

filter가 true일 때 쿼리가 fetch된다.

위와 같이 status === 'loading' 이지만 fetching === 'idle' 인 상황에서는 isLoading flag를 사용해줄 수 없다. 실제로 fetching이 되고 있는 상태가 아니기 때문이다. 이럴 때, isInitialLoading를 사용하여 로딩을 보여줄 수가 있다.

keepPreviousData

keepPreviousData: true

와 같이 하면 refetch 되는 동안 전에 캐싱된 데이터를 보여준다.

Paginated Queries & Infinite Queries

React Query는 페이지네이션과 무한 스크롤 기능을 유용하게 해준다.
paginated queries 공식문서
infinite queries 공식문서

Placeholder Query Data

initialData와 유사하지만 캐싱이 되지 않는다는 점에서 차이점이 있다. 실제 데이터가 fetch 되기 전에 보여줄 데이터를 설정하는 데 쓰이며, 다음과 같이 다른 query 로 부터 이미 캐싱된 데이터를 불러와 그 데이터를 placeholder query data 로 써줄 수 있다.

function Todo({ blogPostId }) {
  const result = useQuery(['blogPost', blogPostId], () => fetch(`/blogPosts/${blogPostId}`), {
    placeholderData: () => {
      // Use the smaller/preview version of the blogPost from the 'blogPosts' query as the placeholder data for this blogPost query
      return queryClient
        .getQueryData(['blogPosts'])
        ?.find(d => d.id === blogPostId)
    },
  })
}
profile
개발하면서 행복하기

0개의 댓글