
fetching : 데이터를 받아오는 중인 상태.
fresh : 최신화 상태의 데이터. 컴포넌트의 상태가 변경되어도 다시 불러오지 않는다.
stale : 최신화가 필요한 데이터. 컴포넌트의 상태가 변경되면 refetch를 한다.
inactive : 현재 사용중이지 않은 상태의 쿼리. cacheTime이 만료되면 deleted 상태가 된다.
deleted : 가비지 컬렉터에 의해 삭제된 상태
staleTime : 데이터가 fresh에서 stale 상태로 변경되는데 걸리는 시간
cacheTime : 데이터가 inactive 상태일 때 deleted가 되기전 caching되는 시간.
1. get : Read -> 가져오는거
=> useQuery 훅
: 쿼리 키와 비동기 함수(패칭 함수)를 인자로 받아 데이터를 가져오고, 로딩 상태, 오류 상태, 그리고 데이터를 반환한다.
- 로딩 상태, 오류 상태 등을 자동으로 반환하기 때문에 redux-thunk에서처럼 일일히 모든 상태를 직접 세팅할 필요가 없다.
- data, error, isFetching, refetch 등 다양한 반환값과 옵션들을 가지고 있다.
- 헷갈릴만한 값으로 isFetching과 isLoading이 있는데 둘의 차이는 아래와 같다.
둘은 목적이 조금 다르기에 Loading indicator를 어떤 방식으로 나타내냐에 따라 적합한 값을 취하면 좋을 것 같다.
- isFetching : 데이터 요청중인 상태 (boolean)
- isLoading : 캐싱이 되어 있지 않은 데이터를 요청중인 상태
즉, 최초 데이터 요청시 isLoading, isFetching이 true인 상태이고 이후에는 캐싱이 되어있기에 isFetching은 true, isLoading은 false라고 생각하면 된다.2. modify : Create, Update, Delete -> 수정하는거
=> useMutation (mutation : 돌연변이. -> 변경이 일어난다는 뜻)
: 데이터를 생성, 수정, 삭제하는 등의 작업에 사용되는 훅
- CUD에 대한 비동기 작업을 쉽게 수행하고, 성공 또는 실패 시에 추가적인 작업을 실행할 수 있다.
- 변경된 이후 데이터를 최신화하기 위해 onSuccess 옵션을 사용할 수 있으며 queryClient 내부 함수인 invalidateQueries를 통해 Key를 stale한 상태로 변경하면 변경과 동시에 새로운 정보로 업데이트 할 수 있다.
- queryClient.invalidateQueries() : Key가 포함된 모든 쿼리를 stale한 상태로 변경. mount가 되었을 때 refetch한다.
- queryClient.refetchQueries() : Key가 포함된 모든 쿼리를 refetch. { active: true } 등의 옵션을 통해 조건을 변경할 수 있다.
3. refresh
=> invalidateQueries (유효화 하지 않는다. -> 무효화 한다.)
: 특정 쿼리를 무효화하여 데이터를 다시 패칭하게 하는 함수.
- 주로
useMutation과 함께 사용하여 데이터가 변경된 후 관련 쿼리를 다시 가져오도록 한다.- 이를 통해 데이터가 항상 최신 상태로 유지될 수 있도록 도와준다.
ex) 새로운 할 일을 추가한 후 기존의 할 일 목록을 다시 가져오도록 하는것- 데이터를 캐싱하는 기준(서버에 다시 요청하지 않고 가지고 있는 기준)은 Query Key 이다.
- Query Key가
더이상 유효하지 않다고 알려주는게 invalidateQueries 이다.- invalidateQueries 할때는 반드시 쿼리키를 넣어줘야한다.
yarn add @tanstack/react-query
import {
useQuery,
useMutation,
useQueryClient,
QueryClient,
QueryClientProvider,
} from '@tanstack/react-query'
import { getTodos, postTodo } from '../my-api'
// Create a client
const queryClient = new QueryClient()
function App() {
return (
// Provide the client to your App
<QueryClientProvider client={queryClient}>
<Todos />
</QueryClientProvider>
)
}
function Todos() {
// Access the client
const queryClient = useQueryClient()
// Queries
const query = useQuery({ queryKey: ['todos'], queryFn: getTodos })
// Mutations
const mutation = useMutation({
mutationFn: postTodo,
onSuccess: () => {
// Invalidate and refetch
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
})
return (
<div>
<ul>{query.data?.map((todo) => <li key={todo.id}>{todo.title}</li>)}</ul>
<button
onClick={() => {
mutation.mutate({
id: Date.now(),
title: 'Do Laundry',
})
}}
>
Add Todo
</button>
</div>
)
}
render(<App />, document.getElementById('root'))
리액트쿼리를 사용하고자 하는 컴포넌트에 QueryClientProvider contextAPI로 감싼다.
queryClient 생성자를 client props로 넘겨준다.
useQueryClient로 queryClient를 생성한다.
useQuery를 사용하여 data를 호출한다.
useMutation으로 데이터를 insert, update, delete 한다.
성공시 invalidateQueries 로 무효화 시킨다.