queryFn 의 매개변수로 Abort Signal 을 받을 수 있고, 이를 이용해서 Query 취소를 가능하게 합니다.
QueryFunctionContext
queryFn 은 매개변수로 QueryFunctionContext 이란 객체를 받습니다.
export const getTodos = async (queryFnContext) => {
const { queryKey, pageParam, signal, meta } = queryFnContext;
// queryKey: 배열형태의 쿼리키
// pageParam: useInfiniteQuery 사용 시 getNextPageParam 실행 시 적용
// signal: AbortSignal 을 의미 (네트워크 요청을 중간에 중단시킬 수 있는 장치)
// meta: query에 대한 정보를 추가적으로 메모를 남길 수 있는 string 필드
const response = await axios.get("http://localhost:5000/todos", { signal });
return response.data;
};
useQuery({
queryKey: ["todos"],
queryFn: getTodos,
})
// example: <div onClick={(event) => {}}
페이지 컴포넌트 umount 시 Query 취소
API 요청 시 기본설정은 컴포넌트가 unmount 되도 네트워크 요청은 중단되지 않습니다.
GET 요청 시 abort signal 이 옵션으로 들어간 경우에만 unmount 시 자동으로 네트워크 취소가 됩니다.
import axios from 'axios'
const query = useQuery({
queryKey: ['todos'],
queryFn: ({ signal }) =>
axios.get('/todos', {
// Pass the signal to `axios`
signal,
}),
})
-수동으로 쿼리 취소
const query = useQuery({
queryKey: ['todos'],
queryFn: async ({ signal }) => {
const resp = await fetch('/todos', { signal })
return resp.json()
},
})
const queryClient = useQueryClient()
return (
<button
onClick={(e) => {
e.preventDefault()
queryClient.cancelQueries({ queryKey: ['todos'] })
}}
>
Cancel
</button>
)
Optimistic Updates
서버 요청이 정상적으로 잘 될거란 가정하에 UI 변경을 먼저하고, 서버 요청 하는 방식. 혹시라도 서버 요청이 실패하는 경우, UI 를 원상복구(revert / roll back)합니다.
Prefetching
페이지 이동 전에 이동할 페이지의 쿼리를 백그라운드에서 미리 호출 (prefetching) 합니다.
캐시 데이터가 있는 상태로 해당 페이지로 이동 시 로딩없이 바로 UI를 볼 수 있습니다.
const prefetchTodos = async () => {
// The results of this query will be cached like a normal query
// prefetch 할 queryKey와 queryFn 은 이동할 페이지의 쿼리와 동일해야 적절합니다.
await queryClient.prefetchQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
})
}
Paginated / Lagged Queries
다른 페이지 클릭 시 매번 Loading UI를 보여주기보다는 기존 UI를 유지하다가 서버로부터 새로운 데이터를 받아왔을 때 바꾸는 방식을 적용할 수 있습니다.
useQuery의 옵션 중 keepPreviousData를 true 로 바꾸면 이전 캐시데이터를 기반으로 isLoading 여부를 판단하게 합니다.
Infinite Queries
Data Fetching 이 일어날 때 마다 기존 리스트 데이터에 Fetched Data 를 추가하고자 할 때 유용하게 사용할 수 있는 hook 입니다.
더보기 UI 또는 무한스크롤 UI 에 사용하기에 적합합니다.
queryFn 실행 → 캐시 데이터 등록 { pages, pageParam } → getNextPageParam 실행 (리턴된 NextPageParam는 훅 내부 메모리에 저장. 캐시에 저장X) → (NextPageParam 이 undefined이 아니면) hasNextPage true로 상태변경 → fetchNextPage 실행 → queryFn 실행 (이 때 내부적으로 저장되어 있던 NextPageParam을 queryFn 의 매개변수로 넘겨줌)