React Query 공부 (1)

JunSeok·2023년 1월 14일
0

react-query

목록 보기
2/11
post-thumbnail

react-query 사용 방법

공식 docs
굉장히 친절하다.

1. react-query를 install

npm install react-query

2. create QueryClient

- QueryClient는 queries와 server data cache를 관리해준다.

3. Apply QueryProvider

- QueryProvider는 query client를 값으로서 사용한다. 즉 client를 props로 간주하고 client는 cache data와 기타 다른 모든 옵션들을 가지고 있다.

- cache data와 모든 QueryClient 구성을 내부 children component에 제공해준다.
- 즉 QueryClientProvider로 감싸진 모든 children components들은 react-query hook을 사용할 수 있다.
// App.tsx

import { QueryClient, QueryClientProvider } from 'react-query'

const queryClient = new QueryClient();

function App()
{
 	return (
     <QueryClientProvider client={queryClient}>
      <div>
      	... 내부 page
      </div>
    </QueryClientProvider>
    )
}

4. run useQuery
- useQuery는 서버에서 데이터를 가져오는 hook이다.
- useQuery가 리턴하는 오브젝트는 아주 많은 property를 가지고 있다.
- 공식 Docs
- useQuery는 인자를 3개 받는다.
- query key : 받고 싶은 데이터로 이름짓는다.
- query function: 데이터를 실제로 가져오는 function 이름을 적어준다. 즉 query function은 데이터를 가져오는 비동기 함수여야 한다.
- 마지막은 option을 적는 곳이다. 이는 나중에 후술할 예정

// post.tsx
import { useQuery }  from 'react-query'

const fetchPosts = async () => {
	const response = await fetch("https://jsonplaceholder.typicode.com/posts?_limit=10&_page=0") 
    return response.json()
}

const { data } = useQuery("posts", fetchPosts, {})

사용방법은 끝이다.
위에서 받은 data를 가지고 사용하면 된다.

useQuery 리턴 값

공식 Docs

앞서 사용한 data 또한 useQuery의 리턴 값이다.
이것 말고도 자주 사용하는 것으로 isLoading과 isError가 있다.
이를 사용함으로써 로딩과 에러 관련 상태를 따로 설정해주지 않아도 되기 때문에 편리하다.
그리고 error는 toString()을 거쳐 화면에 렌더링해주면 실제 에러 메시지를 보여줄 수 있다.

간단한 사용 예시

const { data, isLoading, isError, error } = useQuery("posts", fetchPosts, {})

if(isLoading) return <h3>Loading...</h3>
if(isError) return <><h3>Oops, something went wrong</h3><p>{error.toString()}</p></>

isFetching vs isLoading

isFetching이란 것도 있는데 isLoading과 비교해보자

이 둘의 가장 큰 차이는 기존에 캐시된 데이터가 있느냐 없느냐 이다.

즉 캐시된 데이터가 없고 데이터를 처음 가져오는 상황이라면 isLoading을 사용하고

기존 데이터가 있고, 데이터를 refetch 해야하는 상황이라면 isFetching을 사용한다.

retry 설정

react-query에서 데이터를 가져오는데 에러가 발생하면 default 값으로 retry를 3번한다.
이는 useQuery options 값에서 사용자가 다시 설정할 수 있다.
공식 docs

React-query dev tools

react-query dev tools는 앱에 추가할 수 있는 컴포넌트이며, 이는 개발 도중 모든 query들의 상태들을 보여주며 개발에 도움을 주는 도구이다.
공식 Docs

  • 사용중인 query들을 보여준다.
    - query들의 status
    - 마지막 update 시기

  • query를 통해 불러온 data를 보고 확인할 수 있다.

모든 query들을 관리하는 tool 이기 때문에 민감할 수 있는 부분이지만 기본적으로 product bundle에는 포함되지 않는다고 명시되어 있다.

사용방법

// App.tsx
import { ReactQueryDevtools } from 'react-query/devtools

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      // 내부 props
      <ReactQueryDevtools />
    </QueryClientProvider>
  );
  
}

이렇게 추가해주면 앱을 실행했을 때, 화면 왼쪽 하단에 react-query flower를 볼 수 있을 것이다.
클릭하면 사용중인 모든 query들을 볼 수 있고 관리할 수 있다.
매우 유용한 도구이다.

query state와 stale, stale time

devtools를 보면 query state를 볼 수 있다.
보면 데이터가 stale 상태임을 확인할 수 있다.

react-query에서 데이터는 기본적으로 stale 상태이다. reload 또는 refocus하게 되면 fetching => fresh => 곧바로 stale로 바뀐다.

여기서 가장 중요한 점은 react-query에서는 오직 stale 상태의 데이터만 refetch한다는 것!

여기서 우리는 stale time이란 것을 설정할 수 있다.
stale time은 default 값이 0으로 설정되어 있는데, 0이기 때문에 fresh 상태에서 바로 stale 상태로 바뀌는 것이다.

즉 데이터를 업데이트하고 10초 정도 지난 데이터까지는 웹에서 사용하기에 무리 없어! 라고 생각하면 stale time을 10초라 설정하는 것이다.
=> stale time을 10초라 설정하면 페이지를 리로드했을 때, 데이터가 fresh 상태를 10초동안 유지하고 stale 상태로 바뀜을 알 수 있다.

따라서 stale time은 데이터의 특징마다 달리 해야 한다. 즉각적인 업데이트가 필요한 데이터인 경우 stale time이 매우 짧아야 할 것이다. stale time이 짧아야 빨리 데이터가 stale 상태로 갈 수 있고 stale 상태가 되어야만 데이터가 refetch 될 수 있기 때문이다.

stale time 설정 방법

stale time은 useQuery의 option 값으로 설정할 수 있다.
시간은 ms단위로 설정한다.

// staleTime을 2초라 설정한 경우
const { data } = useQuery("posts", fetchPosts, { staleTime: 2000 }

cache time과 stale time

앞서 말했듯이 stale time은 데이터를 refetching 할 때 고려해야할 사항이다.

사용자가 설정해둔 cache time이 지나면 이전의 cache data는 만료되어 쓰레기 데이터가 된다. (default 값은 5분이며 stale time과 같은 방식으로 재설정가능하다.)

앱에서 새로 데이터를 가져올 때, 만료될 캐시 데이터는 화면에 잠시 보여지는 데이터로 쓰일 수 있다. 즉 데이터를 다시 가져오는 동안 빈 페이지를 보여주는 것보다 시간이 좀 지난 데이터라도 보여주는 것이 낫기 때문이다.

하지만 조금이라도 지난 데이터를 보여주지 않는 것이 좋은 환경이라면 cache time을 0으로 설정할 수 있다.

profile
최선을 다한다는 것은 할 수 있는 한 가장 핵심을 향한다는 것

0개의 댓글