Develope/개발일지

QueryFunctionContext을 고민하면서..

oper0116 2024. 7. 2. 22:35
반응형

QueryFunctionContext를 이용하게 된 계기

NextJS, React-Query를 이용하여 프로젝트를 진행하며, getServerSideProps 에서 Prefetch 기능을 사용하여, 서버사이드렌더링(SSR)을 진행하고자 하였다.

현재 프로젝트에서 사용하고 있는 API 구조는 아래와 같았으며,

{
    resultCode: 200,
    data: {
        ...
    }
}

API 에서 전달해주는 데이터를 클라이언트에서 바로 사용하는 구조가 아니라 클라이언트에서 데이터를 한번 가공하는 형태로 사용하고 있는 형태로 사용하고 있다. (BFF 구조가 되었다면 더 편했을까?)

// Network.ts
async function fetchPage(): Promise<ParsePageType> {
    const response = axios.post<PageType>('/page', ...);

    try {
        return parsePage(response.data.data);
    } catch(e) {
        throw new Error('parsed Error');
    }
}

// Queries.ts
const prefetchPageQuery = () => {
    return queryClient.prefetchQuery({
        queryKey: ["page"],
        queryFn: () => fetchPage(),
    });
};

const usePageQuery = () => {
    return useQuery({
        queryKey: ["page"],
        queryFn: () => fetchPage(),
    });
};

Network.ts가 어떠한 역할을 처리해야할지 아래의 두가지 역할에 대하여 고민을 해보았다.

  1. 클라이언트에서 사용하는 데이터의 형태로 데이터를 전달한다.
  2. API 서버에서 응답값으로 오는 데이터를 전달한다.

1번과 같은 경우네는 Network.ts 파일에서 데이터를 가공하여 리턴해주면 되기에 현재와 같은 구조를 생각해볼수 있으며, 2번의 경우에는 prefetchQuery, useQueryqueryFn에서 각각 처리를 해주어야 하는 경우가 발생하였다.

그러기에 이러한 상황에 대응하기 위한 방법을 찾아보았고 2번의 이러한 이슈를 해결하는 방법을 고민하였고 selectQueryFunctionContext에 대하여 찾아 보았다.

현 상황에서는 select를 사용하여 처리하는 방법은 프로젝트 상황에서 적절치 못하다고 판단하여, QueryFunctionContext를 이용하여 처리하는 방법을 선택하게 되었다.

적용하여 작성된 코드

기존의 코드들을 QueryFunctionContext를 이용하여 아래와 같이 변경하였다.

// 변경전

// Network.ts
async function fetchPage<T extends pageType>(): Promise<T> {
    const response = axios.post<T>('/page', ...);
    return response.page;
    try {
        return parsePage(response.data.data);
    } catch(e) {
        throw new Error('parsed Error');
    }
}

const pageQueryFunctionContext = async ({ queryKey }) => {
    const [ , { ...key }] = ctx
    const data = await fetchPage();

    try {
        return parsePage(response.data.data);
    } catch(e) {
        throw new Error('parsed Error');
    }
}

// Queries.ts
const prefetchPageQuery = () => {
    return queryClient.prefetchQuery({
        queryKey: ["page"],
        queryFn: pageQueryFunctionContext,
    });
};

const usePageQuery = () => {
    return useQuery({
        queryKey: ["page"],
        queryFn: pageQueryFunctionContext,
    });
};

이러한 작업을 통하여 fetchPage를 처리하는 prefetch, useQuery, getQueryClient에서 공통으로 사용할수 있도록 리팩토링을 진행하였다.

마치며

이 글에서 QueryFunctionContext을 사용함에 있어 고민하였던 부분에 중점을 두어 작성하였기에 실질적인 코드 및 타입등을 작성하지 않았으며, QueryFunctionContext을 사용을 고민하여 적용여부를 검토하는 중이라면, Leveraging the Query Function Context 에 들어가서 타입 및 queryKey를 통한 처리들을 확인해보아도 좋을거 같다.

반응형

'Develope > 개발일지' 카테고리의 다른 글

Workbox 캐싱기능을 사용한 PWA 개발  (0) 2020.06.08