리팩토링 이유 📖
Tanstack Query를 사용하면서 여러 컴포넌트에서 중복되는 로직이 발생해 유지보수가 어렵다는 생각이 들었습니다. 그래서 `useQuery`와`useMutation`을 커스텀 훅으로 리팩터링 하고 `queryKey`를 상수화 해 코드의 가독성과 재사용성을 높인 방법에 대해서 공유해보려고 합니다.
기존 코드 📖
useQuery, useMutation
기존에는 `useQuery`와 `useMutation`을 각 API 호출마다 직접 사용했는데, 여러 컴포넌트에서 중복되는 로직이 많아지고 가독성이 떨어 지는 문제가 있었습니다.
const { data: results, isLoading } = useQuery({
queryKey: ["results"]
queryFn: getTestResults,
});
const { mutate } = useMutation({
mutationFn: updateTestResultVisibility,
onSuccess: () => {
queryClient.invalidateQueries(["results"]);
},
})
그리고 `queryKey`를 직접 작성하다보니 지금은 상관없지만 팀 프로젝트와 같이 여러 명이 같이 수정하는 상황에서는 알파벳 하나 잘못 쓰는 걸로 휴먼 에러가 발생할 수 도 있는 상황이 생길 수 있기 때문에 리팩토링을 결정했습니다.
queryKey: ["results"]
리팩토링 코드 📖
queryKey 상수화
먼저 `queryKey`를 상수로 관리해 재사용할 수 있게 했습니다.
export const queryKeys = {
userController: {
userInfo: () => ["userInfo"],
},
resultController: {
results: () => ["results"],
},
};
useQuery 분리
여러 컴포넌트에서 사용하는 useQuery를 `useQuerys.js`파일을 따로 만들어서 분리시켰습니다.
// 사용자 프로필 가져오기
export const useGetUserProfileQuery = () => {
return useQuery({
queryKey: queryKeys.userController.userInfo(),
queryFn: getUserProfile,
});
};
// MBTI 결과 가져오기
export const useGetTestResultsQuery = () => {
return useQuery({
queryKey: queryKeys.resultController.results(),
queryFn: getTestResults,
});
};
useMutation 분리
useMutation도 `useMutations.js`파일을 따로 만들어서 분리를 시켰습니다.
// 공개, 비공개 전환 업데이트
export const useUpdateVisibilityMutation = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: updateTestResultVisibility,
onSuccess: () => {
queryClient.invalidateQueries(queryKeys.resultController.results());
},
});
};
// MBTI 결과 삭제
export const useDeleteTestResultMutation = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: deleteTestResult,
onSuccess: () => {
queryClient.invalidateQueries(queryKeys.resultController.results());
},
});
};
// 닉네임 업데이트
export const useUpdateNicknameMutation = () => {
const queryClient = useQueryClient();
const [data, setData] = useState(null);
return useMutation({
mutationFn: updateProfile,
onSuccess: (response) => {
setData(response);
queryClient.invalidateQueries(queryKeys.userController.userInfo());
},
});
};
컴포넌트
해당 컴포넌트에서 호출해 간편하게 사용할 수 있습니다.
const { data: results, isPending, isError } = useGetTestResultsQuery();
const { mutate: updateMutate } = useUpdateVisibilityMutaion();
const { mutate: deleteMutate } = useDeleteTestResultMutaion();
회고 🧐
가독성, 재사용성
API 호출 로직을 분리해 코드가 깔끔해졌고, 동일한 API 호출 로직을 여러 컴포넌트에서 재사용할 수 있어 중복을 줄였습니다. 이번 리팩토링을 통해 코드의 품질과 유지보수성을 크게 향상할 수 있었고 쿼리키를 상수화 시킨 방법은 나중에 협업을 진행할 때 아주 긍정적인 영향이 미칠 것 같습니다.
아직 많이 부족합니다! 조언은 언제나 환영입니다~!
'공부 > 프로젝트' 카테고리의 다른 글
[팀 프로젝트] issue daily (2) | 2024.10.17 |
---|---|
[팀 프로젝트] Go 캠핑! (1) | 2024.09.23 |
[리팩토링] 커스텀 훅을 활용한 날씨 데이터 관리 구조 개선 (1) | 2024.09.15 |
[개인 프로젝트] MBTI 테스트 (0) | 2024.09.14 |
[팀 프로젝트] 방콕 스타일 회고 (0) | 2024.09.04 |
[팀 프로젝트] 방콕 스타일 (2) | 2024.09.04 |
[팀 프로젝트] 방콕스타일 - 검색 기능 구현 (Debounce) (3) | 2024.09.02 |
[팀 프로젝트] 방콕스타일 - 좋아요 기능 구현 (1) | 2024.09.02 |