안녕하세요, 이번 글은 'React Query 잘 사용하기' 시리즈의 마지막 글입니다. 이번 글에서는 앞서 설명한 queryKey, Custom hook 등 다양한 React Query 관련 코드를 어떻게 관리했는가에 대해 이야기 해보고자 합니다.
사용 버전 : @tanstack/react-query : v4.35.3
들어가기 앞서..
아래의 내용이 React Query를 사용하는 Best Practice가 아닙니다. 많은 시행착오를 겪으며 나름대로 정립한 React Query 사용법을 공유하는 글 입니다. 건설적인 태클과 지적, 제안은 언제나 환영입니다!
1. Query Key 관리하기
2. Custom hook 사용하기
React Query를 잘 사용하기 위해 API 호출을 여러 단계로 추상화하고, React Query hook을 Custom hook으로 분리하는 등 다양한 시도를 했습니다. 이 과정에서 이 코드는 어디에 위치하는 것이 좋을 지, 이 코드는 별도의 파일로 분리하는 것이 좋을 지 합치는 것이 좋을 지 등 폴더 구조와 파일 관리에도 많은 고민을 했습니다.
이번 글에서는 제가 어떤 고민을 했고, 어떤 선택을 하였는 지, 채택한 방법의 장점과 단점에 대해 이야기 해보고자 합니다.
① 사용한 폴더 구조 설명
먼저 제가 사용한 폴더 구조를 보여드리겠습니다.
우선 저는 API 호출과 관련된 모든 코드를 src/api
폴더에 위치하도록 하였습니다.
src/api
┣ 📂endpoints
┗ 📂reactQuery
조금 더 자세히 살펴보자면 아래와 같습니다.
/endpoints
폴더/reactQuery
폴더src/api
┣ 📂endpoints
┃ ┣ 📂artworks
┃ ┃ ┣ 📜artworks.d.ts
┃ ┃ ┣ 📜index.ts
┃ ┃ ┣ 📜useDeleteArtworksCategory.ts
┃ ┃ ┣ 📜useFetchAdminList.ts
┃ ┃ ┣ 📜usePatchArtworksCategory.ts
┃ ┃ ┣ 📜usePostArtworksCategory.ts
┃ ┃ ┣ ...
┃ ┣ 📂commonCodes
┃ ┃ ┣ 📜index.ts
┃ ┃ ┗ 📜useFetchCommonCode.ts
┃ ┣ 📂typings
┃ ┃ ┗ 📜endpoints.ts
┃ ┗ 📜index.ts
src/api
┗ 📂reactQuery
┃ ┣ 📂typings
┃ ┃ ┣ 📜query.ts
┃ ┃ ┗ 📜queryKeys.ts
┃ ┣ 📜index.ts
┃ ┣ 📜queryClient.ts
┃ ┣ 📜queryKeys.ts
┃ ┣ 📜useMutation.ts
┃ ┗ 📜useQuery.ts
그리고 각 폴더 아래 index.ts
파일을 포함하여, 폴더 내의 파일들을 하나로 묶어 외부에서 쉽게 가져다 사용할 수 있도록 하였습니다.
예를 들어, artworks 폴더 내의 index.ts 파일을 살펴보면 아래와 같이 이루어져 있습니다.
// artworks/index.ts
export * from './useFetchAdminList.ts';
export * from './useDeleteArtworksCategory.ts';
// 나머지 모든 파일들도 같은 방식으로 export
그리고 endpoints 폴더에도 index.ts 파일이 존재해, endpoints 하위의 모든 폴더와 파일을 하나로 묶어 export 하였습니다.
// endpoints/index.ts
export * from './artworks';
export * from './commonCodes';
// 나머지 모든 폴더,파일들도 같은 방식으로 export
이렇게 하면 외부에서 해당 폴더에 접근할 때 여러 개의 import 문을 작성하는 번거로움 없이 간결하게 코드를 작성할 수 있습니다.
import { useFetchAdminList, useDeleteArtworksCategory } from '@api/enpoints';
이러한 구조는 많은 장점을 가져다 주었습니다. 코드의 가독성을 높이고 유지보수를 쉽게하며, 새로운 파일을 추가하거나 기존 파일을 제거할 때도 index.ts 파일만 수정하면 되므로 관리가 편리하다는 장점이 있습니다.
② 장점과 단점
이러한 폴더 구조를 채택함으로써 많은 장점이 있었지만, 이건 좀 불편하다고 느낀 단점도 존재했습니다.
③ 개선 방향
위에서 언급한 단점 중, QueryKey를 단 하나의 파일로만 관리하는 방식으로 인한 불편함이 매우 크게 느껴졌습니다. 애플리케이션의 크기가 점차 커질 수록 QueryKey 파일도 점차 커져 마지막 쯤에는 거의 200줄 이상이 넘는 코드를 포함하는 거대한 파일이 되어버렸습니다. 어디 위치에 새로운 쿼리 키를 추가할 지, 기존에 사용하던 쿼리 키는 어디에 위치하는 지를 찾기 매우 번거로웠습니다.
그래서 중앙 집중형 방식의 QueryKey 관리보다는 적절히 나눠서 관리하는 방법이 필요함을 느끼게 되었습니다.
다음에 프로젝트를 진행한다면, 아래와 같이 endpoints 별로 QueryKey를 나누어 관리할 것 같습니다.
src/api
┣ 📂endpoints
┃ ┣ 📂artworks
┃ ┃ ┣ 📜artworks.d.ts
┃ ┃ ┣ 📜index.ts
┃ ┃ ┣ 📜artworks.keys.ts
┃ ┃ ┣ ...
artworks 관련 api 호출을 모두 관리하는 artworks
폴더 안에서 artwork.keys.ts
라는 별도의 파일로 QueryKey를 관리하는 것 입니다. 이렇게 하면, 각 endpoints 별로 QueryKey를 관리할 수 있기 때문에 적절한 수준의 모듈화를 통해 유지보수에도 효과적일 것 입니다.
그리고 page, limit, sortDirection, sort 등 중복해서 사용되는 parameter는 기존의 src/api/reactQuery/queryKeys.ts
에서 선언하고 필요한 곳에서 import하여 사용하면 훨씬 더 간편하게 사용할 수 있으리라 생각됩니다.
물론 위 방법은 모든 프로젝트에 적용할 수 있는 Best Practice는 아니기 때문에 이를 참조하여 봐주시길 바랍니다.
이번 시리즈에서는 React Query를 상용 프로젝트에 적용하고 개선한 경험을 통해 얻은 인사이트와 시행착오의 경험을 위주로 이야기 했습니다. 이 시리즈가 React Query를 도입하고자 하는 팀에게 조금이나마 도움이 되었기를 바라며 글을 마치도록 하겠습니다. 여기까지 와주신 모든 분들에게 감사의 말을 전합니다. 감사합니다!
https://www.reddit.com/r/reactjs/comments/18z3nsi/tanstack_react_query_architecture/