리액트쿼리 도입기
1. 리액트쿼리를 왜 써야할까?
- 우선적으로 클라이언트 단에서 사용하는 데이터는 크게 2가지로 나눌 수 있다.
첫번째는 클라이언트 단에서 사용자에게 받는 데이터와 두번째는 서버에서 받아와 사용하는 데이터이다.
클라이언트는 2가지의 성격을 가진 데이터를 사용하기 때문에 혼용을 겪을 수 있다.
가령, 신청 폼에 입력한 값을 클라이언트가 서버에 post 해주었지만, 새로고침 했을 때 서버에 패치된 즉, update된 값이 아니라 이전에 클라 단에서 가지고 있던 이전 값을 뷰에 띄울 수 있는 문제 상황이 발생할 수 있다.
이러한 혼용을 막기 위해 서버의 데이터를 클라이언트를 가져올 때 사용할 수 있는 대안이 있는데, 그것이 리액트쿼리이다.
기본적으로 클라/서버 단의 데이터를 분리할 수 있다는 점에서 큰 이점을 가지며,
이와 비슷하게 리액트쿼리는 캐싱이나 업데이트(데이터가 오래된 경우)와 같은 비동기 처리 과정에서도 이점을 가진다.
2. 기본적인 사용법
- 사용법은 커스텀 훅과 유사하며, 리액트쿼리를 사용하기 위해선 상단에 세팅이 필요하다. 설치는 이 자료를 참고.
아래와 같이 QueryClient 객체와 QueryClientProvider태그를 통해 최상단 컴포넌트 App에 지정해준다.
import type { AppProps } from 'next/app';
import { QueryClient, QueryClientProvider } from 'react-query';
function MyApp({ Component, pageProps }: AppProps) {
// 새롭게 지정
const queryClient = new QueryClient();
return (
<QueryClientProvider client={queryClient}>
<RecoilRoot>
<ThemeProvider theme={theme}>
<GlobalStyle />
<Component {...pageProps} />
</ThemeProvider>
</RecoilRoot>
</QueryClientProvider>
);
}
export default MyApp;
- 자주 사용되는 API와 중요한 개념을 살펴보자.
1) useQuery
import { useQuery } from 'react-query'
function App() {
const info = useQuery('todos', fetchTodoList)
}
- Query란?
unique한 키, 즉 query 키에 묶여있는 하나의 비동기 소스를 query라고 한다.
주로 서버에서 패치되는 get과 post와 같은 프로미스 객체에 query가 쓰일 수 있다.
만약 서버에서 데이터를 변경하고 싶다면, Mutation을 쓰는 것을 권장한다.
- useQuery의 인자
1. query를 위한 unique한 key
2. 에러나 resolve 상태를 반환할 수 있는 Promise 객체, 즉 비동기함수
- useQuery의 반환값
반환값의 상태는 4가지가 있을 수 있다.
1. isLoading - 데이터를 갖지 않거나, fetching 상태일 때
2. isError - 에러
3. isSuccess - 성공적으로 데이터 반환
4. isIdle - 쿼리가 불가능한 상태일 때
또한 반환값으로는 아래와 같이 있을 수 있다.
1. error - isError
2. data - isSuccess
3. isFetching - 쿼리가 패칭하고 있는 어느 상태일 때 해당값을 반환
- query key에 대해 (feat. 스트링뿐만 아니라 변수를 사용하는 이유)
query function이 외부 변수에 의해 결정되는 경우, query key에 변수를 포함해줌으로써 이득을 얻을 수 있다.
아래 한 가지 예시를 통해 살펴보자.
쿼리에 대해 데이터를 가져올 때, 버튼을 누르면 필터링된 데이터를 다시 가져오는 상황이라고 하자.
따라서 필터링 되도록 데이터를 변경하기 위해서는 아래와 같이 작성해줘야한다.
function Component() {
const [filters, setFilters] = React.useState()
const { data } = useQuery(['todos', filters], fetchTodos)
return <Filters onApply={setFilters} />
}
데이터를 변경하는 state가 있고, 그에 해당하는 key가 변경될 때마다 query를 받아온다.
이때 자동으로 refetch되기 때문에 key에 저장만해놓으면 된다! 따라서 필터를 적용하기 위해서는 state를 set하는 함수(setFilters)를 넣어주면 된다.
이러한 외부에 의해 결정되는 쿼리가 있을 때 변수를 고유한 키에 넣어주는 것이다.
2) useQueries
const results = useQueries({
queries: [
{ queryKey: ['post', 1], queryFn: fetchPost, staleTime: Infinity},
{ queryKey: ['post', 2], queryFn: fetchPost, staleTime: Infinity}
]
})
한 개의 쿼리 객체에 대해 여러 개를 get 해 오고 싶을 땐 useQueries 를 사용하면 좋다.
3) useMutation
function App() {
const mutation = useMutation(newTodo => {
return axios.post('/todos', newTodo)
})
return (
<div>
{mutation.isLoading ? (
'Adding todo...'
) : (
<>
{mutation.isError ? (
<div>An error occurred: {mutation.error.message}</div>
) : null}
{mutation.isSuccess ? <div>Todo added!</div> : null}
<button
onClick={() => {
mutation.mutate({ id: new Date(), title: 'Do Laundry' })
}}
>
Create Todo
</button>
</>
)}
</div>
)
}
- Mutations이란?
쿼리와 다르게 mutation은 데이터를 create/update/delete하며, 서버에 side effect를 일으키는 동작을 수행한다.
해당 과정을 useMutation이라는 API로 수행할 수 있다.
- useMutation의 반환값
반환값의 상태는 4가지가 있을 수 있다.
1. isLoading - mutation이 실행 중일 때
2. isError - 에러
3. isSuccess - 성공적으로 데이터 반환
4. isIdle - mutation이 idle하거나, fresh/reset 상태일 때
또한 반환값으로는 아래와 같이 있을 수 있다.
1. error - isError
2. data - isSuccess
- mutate를 통해 값 전달하기
위의 예제 코드에서 볼 수 있듯이, mutation함수는 mutate를 통해, 특정 변수 혹은 객체를 전달해준다.
그 외에도 mutation과 관련해 reset, mutation side effect, retry에 관해 알고 싶다면,
아래 아티클을 읽어보자..
https://tanstack.com/query/v3/docs/react/guides/mutations
4) invalidateQueries
import { useQuery, useQueryClient } from 'react-query'
const queryClient = useQueryClient()
queryClient.invalidateQueries('todos')
// 아래 두가지 쿼리는 모두 최신화 상태가 된다
const todoListQuery = useQuery('todos', fetchTodoList)
const todoListQuery = useQuery(['todos', { page: 1 }], fetchTodoList)
- 가장 최신의 상태를 유지하기
사용자가 이미 수정한 데이터에 대해 쿼리의 데이터가 가장 최신의 상태가 아니라는 것을 알게된다면 어떤 대안을 사용할 수 있을까?
QueryClient는 invalidateQueries를 통해 stale한 상태를 유지하게 하며, 또한 지속적으로 refetch를 통해 최신의 상태로 만든다.
- invalidateQueries를 사용하면 일어나는 일
1. stale 상태로 지정된다. 즉 데이터가 신선하지 않은 상태로 지정된다. 참고로stale 상태는 staleTime과 함께 사용할 수 있다.
2. stale상태가 되면, invalidate 상태가 된 쿼리가 refetch를 거치게 된다.
이러한 과정으로 최신 값을 갱신할 수 있는 것이다.
https://tanstack.com/query/v3/docs/react/quick-start
Quick Start | TanStack Query Docs
This example very briefly illustrates the 3 core concepts of React Query: Queries
tanstack.com
'Web > React' 카테고리의 다른 글
[ Next.js ] state에 따라 svg파일 색상 바꾸기 | svgr + styled component (0) | 2023.11.04 |
---|