안녕하세요 트리플랩입니다. 정말 오래간만에 글을 쓰는것 같네요~
부지런히 작성해야 하는데ㅠ 회사일이 바쁘다 보니.. 이렇게 설명절 연휴에 작성하게 되네요ㅎㅎ
이번 포스트는 React Query 커스텀에 대해서 이야기를 해볼까 합니다.
참고로 우리팀은 react-query: v5를 사용합니다.
useCustomQuery를 만들어서 사용하는 이유를 간단히 설명하면
shopby라는 이커머스 쇼핑몰 오픈 API를 사용합니다.(헤드레스 기반) 이곳 API를 사용해 보신 분들은 아시겠지만
Parameters로 정말 많은 옵션값들을 서버에 보낼수가 있습니다.
그런데 이것을 useQuery로 서버에 요청을 하다보면 다음과 같이 Parameters의 길이가 보기 힘들게 길어질것 입니다.
const {
data: multiCategory,
isFetching: isFetchingMultiCategory,
error: errorCategory,
} = useQuery({
queryKey: ['/products/search'],
queryFn: async () => {
const { data } = await customAxios(PLATFORMLIST.PC).get<DetailCategory>(
`/categoryNos/${slug}&order.by=${categorySortBy[4].value}&order.direction=DESC&filter.saleStatus=ONSALE`,
);
return data;
},
});
지금은 간단한 예시이지만 이런것들을 점점 많아 질거라 예상해서 미리 사전에 useCustomQuery Hook을 만들어서 관리하기로 했습니다.
Custom Hook
src/hooks/useCustomQuery.ts
import { QueryFunctionContext, useQuery } from '@tanstack/react-query';
import { PLATFORMLIST, VERSION1, VersionList } from '@/constant/axiosRelated';
import { Platform, customAxios } from '@/libs/customAxios';
async function fetchData<T>(
{ queryKey }: QueryFunctionContext,
platform: Platform,
params?: Record<string, unknown>,
customQuery?: string,
version?: VersionList,
) {
const queryString = customQuery || (queryKey[0] as string);
const response = await customAxios(platform, version).get<T>(queryString, { params });
return response.data;
}
export function useCustomQuery<T>({ //👈 이번 포스트의 주요 핵심 내용
queryKey,
platform = PLATFORMLIST.PC,
params,
customQuery,
enabled = true,
version = VERSION1,
}: {
queryKey: QueryFunctionContext['queryKey'];
params?: Record<string, unknown>;
customQuery?: string;
enabled?: boolean;
platform: Platform;
version?: VersionList;
}) {
return useQuery({
queryKey,
queryFn: (context: QueryFunctionContext) =>
fetchData<T>(context, platform, params, customQuery, version),
enabled,
});
}
👉 useCustomQuery위에서 만든 함수를 사용 예시 코드
src/categories/page.tsx
import { useCustomQuery } from '@/hooks/useCustomQuery';
const {
data: productsQuery,
isFetching: isFetchingProductsQuery,
isPending: aPending,
error: errorProductsQuery,
refetch,
} = useCustomQuery<{
items: Product[];
multiLevelCategories: Categories[];
totalCount: number;
}>({
queryKey: ['/products/search/filter'],
platform: PLATFORMLIST.PC,
params: { //👈다음과 같이 객체형식으로 전달이 가능해짐.
categoryNos: Number(slug),
'order.by': orderBy.value,
'order.direction': orderBy.direction,
'filter.saleStatus': 'ONSALE',
'filter.soldout': false,
'filter.totalReviewCount': true,
pageNumber: page,
pageSize: productsLimit,
},
customQuery: '/products/search',
enabled: false,
});