불필요한 네트워크 요청을 제거하는것
export const getTodos = async (queryFnContext) => {
const { queryKey, pageParam, signal, meta } = queryFnContext;
const response = await axios.get("http://localhost:5000/todos", { signal });
return response.data;
};
useQuery({
queryKey: ["todos"],
queryFn: getTodos,
})
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>
)
서버 요청이 정상적으로 잘 될거란 가정하에 UI를 먼저 변경하고 서버에 요청하는 방식
혹시라도 서버 요청이 실패하는 경우, UI를 원상복구 시킨다
onMutate: async (newTodo) => {
console.log("onMutate 호출");
await queryClient.cancelQueries({ queryKey: ["todos"] });
const previousTodos = queryClient.getQueryData(["todos"]);
queryClient.setQueryData(["todos"], (old) => [...old, newTodo]);
return { previousTodos };
},
onError: (err, newTodo, context) => {
console.log("onError");
console.log("context:", context);
queryClient.setQueryData(["todos"], context.previousTodos);
},
onSettled: () => {
console.log("onSettled");
queryClient.invalidateQueries({ queryKey: ["todos"] });
},
페이지 이동 전에 이동할 페이지의 쿼리를 백그라운드에서 미리 호출한다
캐시 데이터가 있는 상태로 해당 페이지로 이동 시 로딩없이 바로 UI를 볼 수 있다
const prefetchTodos = async () => {
await queryClient.prefetchQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
})
}
다른 페이지 클릭 시 매번 Loading UI를 보여주기 보다는 기존 UI를 유지하다가 서버로부터 새로운 데이터를 받아왔을때 바꾸는 방식
Data Fetching이 일어날 때 마다 기존 리스트 데이터에 Fetched Data를 추가하고자 할 때 유용하게 사용하는 hook
const fetchProjects = async ({ pageParam = 0 }) => {
const res = await fetch('/api/projects?cursor=' + pageParam)
return res.json()
}
const {
data,
error,
fetchNextPage,
hasNextPage,
isFetching,
isFetchingNextPage,
status,
} = useInfiniteQuery({
queryKey: ['projects'],
queryFn: fetchProjects,
getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
})