1. useQuery는 쿼리를 즉시 실행하며 필요한 경우 background에서 업데이트를 수행
mutations는 우리가 변형을 원하는 경우 부를 수 있는 mutate함수를 제공해줌
2. useQuery를 다른 컴포넌트에서 여러번 부를 수 있고,
동일한 캐시된 결괏값을 부를 수 있다.
useMutation을 하게 되면 결과를 캐시에 저장하지 않고,
mutation의 결괏값을 반환해줄 것 이다.
구현해야 할 것은
가져오는 데이터가 캐싱되도록 하는 것
너무 많은 요청을 보내게 되면 api 낭비이므로
useQuery는 생성하면
생성당시 staleTime을 지정해두면 (default는 0)
해당 데이터가 stale하다고 판단하여
window에서 focus가 되면 refetch를 하게 됨
staleTime이 지났더라도 focus되기만 해도 refetch되는 동작을 막으려면
refretchOnWindowFocus옵션을 false로 설정
defaultOptions로 해도 되고,
useQuery마다 해
useQuery를 사용하지 않고 useMutation만 사용할 수 있을까?
import { useEffect } from 'react';
import { API_FETCHER, ApiMethods } from '@utils/axiosConfig';
import useMutationggu from './useMutationggu';
import { getKeyFromUrl } from '@utils/getNavProps';
interface UseApiParams {
method?: ApiMethods;
path?: string;
data?: any;
shouldInitFetch?: boolean;
initialResult?: string;
gcTime?: number;
}
const useCachingApi = async ({
method: triggerMethod = 'get',
path: triggerPath = '',
data: triggerData = {},
shouldInitFetch = false,
// initialResult = '',
gcTime = 0,
}: UseApiParams) => {
// }) => {
const key = getKeyFromUrl(triggerPath);
// applyResult = true,
// isShowBoundary = true,
console.log(key);
const keyArr: string[] = [];
keyArr.push(key);
const {
mutate: trigger,
data: result,
isPending: loading,
error,
} = useMutationggu(
keyArr,
async (data) =>
await API_FETCHER[triggerMethod as ApiMethods](triggerPath, data),
gcTime
);
useEffect(() => {
shouldInitFetch && console.log('초기 요청합니다!!');
shouldInitFetch && trigger(triggerPath, triggerData);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const reqIdentifier = triggerMethod + 'data';
return { result, loading, reqIdentifier, trigger, error };
};
export default useCachingApi;
1. POST요청
trigger를 컴포넌트에서 사용 하게 되면
trigger(data)
를 하여 요청할 data를 인수에 넣어주고,
그것은
const {
mutate: trigger,
data: result,
isPending: loading,
error,
...t생략
} = useMutationggu(
keyArr,
async (data) =>
await API_FETCHER[triggerMethod as ApiMethods](triggerPath, data),
gcTime
);
이부분에서 API_FETCHER로 가서
method별로 요청을 보내게 됨
triggerPath는 컴포넌트에서 useApi를 선언할 당시 인수로 넣었던 객체중 path의 key를 사용한다.
위의 data는 mutate를 사용할 때 첫번째 인수로 넣어주면 들어가게 됨
그러니까 사용할 때마다 path가 달라지려면 useApi를 계속해서 새로 선언해주어야 함.
POST요청 이후 응답 함수
POST 요청에 대한 응답은
trigger에 또 option으로 넣어주어도 됨....?
원래는 되는데 한번 useCachingApi에서 useMutationggu로 가게 만든 지금은 모르겠다...!
trigger(todo, {
onSuccess: () => {},
})
applyResult = false
결과를 반영하지 않아야 할 때만
onSuccess부분을 조건문 처리
onSuccess: async () => {
if (applyResult) {
queryClient.invalidateQueries({ queryKey: itemId });
return;
}
return;
},
나머지는 true가 default 값
isShowBoundary true가 default
onError: async (error, variables, context) => {
isShowBoundary && showBoundary(error);
},
App.tsx
<QueryErrorResetBoundary>
<ErrorBoundary onReset={reset} fallback={<Error />}>
2. GET요청
method get이고 gcTime적용해야 할때는 기존 값을 반환해서 캐싱을 적용해야 함
onMutate: async () => {
if (method === 'get' && gc > 0) {
await queryClient.cancelQueries({ queryKey: itemId });
// 기존 Query를 가져오는 함수 ( 존재하지 않으면 undefind 반환 )
const previousValue = queryClient.getQueryData(itemId);
//optimistic UI 현재는 필요없음
// if (previousValue) {
// // setQueryData(): Query의 캐시된 데이터를 즉시 업데이트하는 동기 함수 ( Query가 존재하지 않으면 생성 )
// // 전달받은 variables값을 즉시 새로운 데이터로 업데이트
// queryClient.setQueryData(itemId, (oldData) => [...oldData, variables]);
// }
// 이전 값 리턴
return { previousValue };
}
},
3. UPDATE 요청
data를 trigger의 첫번째 argument로 보내서
요청을 보내고,
성공/실패 여부에 따라
onSuccess 함수 사용
onError일때 함수를 넣어도 되고 안넣어도 됨
(onError일때 toast를 보여줘도 될듯)
4. DELETE요청
UPDATE와 동일
'프로젝트' 카테고리의 다른 글
[에러들 기록] (0) | 2024.02.04 |
---|---|
타입 전역객체로 사용할때 협업시 문제점 (0) | 2024.02.01 |
useApi훅에 react-query활용하여 caching기능 넣어보기(1) (0) | 2024.01.23 |
compound component형태 (0) | 2024.01.07 |
dependencies와 devDependencies의 구분 (0) | 2024.01.04 |