[React-Query] 중복되는 쿼리 로직
프로젝트를 진행하던 중, 중복되는 쿼리 로직이 신경쓰이기 시작했다.
같은 로직인데 여러 파일에서 반복적으로 사용하고 있었고,
수정 사항이 생기면 해당 로직이 있는 각 파일의 위치를 확인하며 일일이 수정해줘야하는게 마음에 들지 않았다.
이러한 불편함을 느끼고 문득, 이런 로직도 '함수처럼 관리하면 쉽지 않을까?' 하는 생각이 들었다.
예를 들어, 날짜를 변환해주는 함수가 있으면 이를 이용해서 날짜 변환이 필요한 곳마다 사용할 수 있다.
이런 개념으로 쿼리 로직도 따로 분류해놓고 필요한 곳에서 골라쓰면 좋지 않을까라는 생각을 했던 것이다.
먼저, 쿼리 폴더를 따로 생성한 후 그 안에 API별 쿼리 파일들을 만들고, 각 쿼리 로직을 파일에 맞게 분리해서 작성했다.
그 다음은 기존의 로직을 약간 변형해야 했다.
// 기존 로직
const { data, isLoading, isError, hasNextPage, fetchNextPage } = useInfiniteQuery<MyLessonResult>(
["my-lesson", { limit: 2, status: "COMPLETED" }],
({ pageParam = 1 }) =>
getMyLessonRequest({
page: pageParam,
limit: 2,
status: "COMPLETED",
}),
{
getNextPageParam: (lastPage, allPages) => {
return lastPage.hasMore ? allPages.length + 1 : undefined;
},
},
);
// 변형한 로직
export const useGetMyLessonList = (userId: string, { limit, status }: LessonParams) => {
return useInfiniteQuery<LessonResult>(
["my-lesson", userId, { limit, status }],
({ pageParam = 1 }) =>
getMyLessonRequest({
page: pageParam,
limit,
status,
}),
{
getNextPageParam: (lastPage, allPages) => {
return lastPage.hasMore ? allPages.length + 1 : undefined;
},
},
);
};
기존의 쿼리 로직을 useGetMyLessonList라는 커스텀 훅으로 만들어 로직을 재사용 가능한 방식으로 추출했다.
또한, 파라미터는 userId, limit, status를 동적으로 받도록 했는데 그 이유는 다음과 같다.
userId는 각 사용자의 데이터를 구분하기 위해 쿼리 키에 고유한 값으로 포함시켰고,
이렇게 함으로써 각 사용자별로 독립적인 데이터를 가져올 수 있었다.
limit과 status는 이 로직을 사용하는 페이지가 여러 곳에 있기 때문에 동적으로 받아올 수 있도록 파라미터로 추가했다.
각 페이지마다 불러오는 데이터가 status에 따라 다르고, limit 또한 페이지별로 다르게 설정되기 때문에,
이를 유연하게 처리하기 위해 limit과 status를 파라미터로 받도록 했다.
const { data, isLoading, isError, hasNextPage, fetchNextPage } = useGetMyLessonList(
userId || "",
{
limit: 4,
status: "PENDING",
},
);
따라서 이제 해당 쿼리 로직이 필요한 페이지에서는 위와 같이 사용할 수 있다.
코드가 더 간결해지고, 가독성과 재사용성이 향상되었음을 알 수 있다.
또한, 수정이 필요할 때에도 쿼리 파일에 있는 해당 로직만 수정하면 되므로 유지보수성도 높아졌다 할 수있다!
해당 방식으로 쿼리 로직을 분리한 뒤 팀원들에게도 좋은 반응을 얻을 수 있었다.
실제 팀원 분의 피어 리뷰 내용:
useGet hook 을 도입하셔서 tanstack-query 를 사용하셨는데, queryKey 관리도 편하고, cache 관리하기도 편해서
저도 도입해서 썼었습니다. 디자인 감각도 좋으셔서 전반적인 UI/UX 관리도 해주시고 많이 배웠던거 같습니다.