학부시절 처음 React로 프로젝트를 진행할 때 디자인 패턴에 대해 정확하게 인지하지 못하고 있었다.
그 때 당시 잡았던 구조와 작성했던 코드를 다시 보면 딱히 디자인 패턴이라고 할 만한 부분이 없었지만 굳이 정하자면 MVC 패턴에 가까웠던 것 같다... 서버 상태 관리 또한 이루어지지 않고 있던 상태였다.
MVC 패턴의 경우 프로젝트의 규모가 커지거나 복잡해질수록 컨트롤러가 비대해진다는 문제가 있었다.
이후 어느정도 여러가지 부분들에 대한 개념이 잡힌 후 Redux, Context API를 사용하여 전역 상태 관리와 서버 상태 관리를 하며, Flux 패턴을 사용하여 당시의 프로젝트들을 진행했다.
Action -> Dispathcer -> store -> view
위와 같이 단방향으로 데이터가 흘러갔기에, 어느정도 예측 가능한 코드를 작성할 수 있었으며, Flux패턴으로 작성 된 코드를 확인했을 때 로직을 조금 더 빠르게 파악할 수 있었다.
Redux를 사용한 프로젝트의 경우 위 패턴에서 Redux-saga, Redux-thunk와 같은 써드파티 미들웨어를 함께 사용해주어 서버 상태를 관리했다.
또한 Context API를 사용한 프로젝트의 경우 React-Query를 곁들여 서버상태를 관리해주었다.
최근에는 MobX, Recoil과 같은 강력한 상태관리 라이브러리들을 접하면서 MVVM 패턴을 사용했다. view와 view Model을 분리하여, view Model에서 로직 및 상태 or 데이터를 처리해주었고 view에서는 useViewModel hook을 사용하여 데이터를 연결하고 단순하게 나타내주는 기능만 처리하도록 하였다.
서버 상태 관리 및 전역 상태 관리는 Recoil & React-Query 조합을 사용하여 진행했다. Recoil을 선택한 이유는 MobX보다는 Recoil이 더 React hook과 비슷해서였다.
View Model에서는 useQuery를 사용하여 API에서 데이터를 fetch했고, onSuccess시 전역적으로 사용할 필요가 있는 데이터는 Recoil Atom에 저장하여 상태로 관리했다. mutation시 쿼리무효화를 진행해주었기에, key가 같은 쿼리에서 refetch가 일어났고, Recoil State또한 바로 update해줄 수 있었다.
문제는 nextJS를 사용하여 SSR을 했을 경우, 위 패턴을 적용할 수 없다는 것이였다.
nextJS에서는 pages 폴더 내에서 파일명으로 라우팅이 이루어졌기에, view와 view Model을 분리하는데 있어서 어려움이 있었다. 또한 getServerSideProps 함수를 사용하여 props로 서버사이드에서 fetch한 데이터를 내려받아 view와 view Model을 완벽하게 분리하는것이 어려웠다.
nextJS 위에서 MVVM 패턴을 사용하는 것은 조금 더 연구가 필요했지만 사실 더 어려움이 있었던 부분은 nextJS에서 React-Query를 함께 사용하여 서버관리를 하는 것이였다.
서버 상태를 관리하기 위해서는 클라이언트쪽에서 useQuery를 사용하여 데이터를 fetch해와야 한다.
getServerSideProps를 사용해 서버사이드에서 데이터를 fetch한 뒤 랜더된 html 파일을 내려 줄 경우 사용자가 빈 페이지를 보고있을 필요가 없지만, 서버 상태 관리를 위해 useQuery와 mutation을 어떤식으로 사용해야 할지 고민이였다.
정답은 React-Query 공식 문서의 SSR 페이지 가이드에서 찾을 수 있었다.
서버사이드에서 fetch한 데이터를 클라이언트 사이드에서 props로 받아 useQuery의 InitialData로 넣어주면 SSR과 함께 효율적으로 서버 상태 관리를 진행할 수 있었다.
https://tanstack.com/query/v4/docs/guides/ssr
(dehydrate와 hydrate를 사용한 방법 또한 있어서 사용해 볼 예정이다!)
여러가지 디자인 패턴을 사용하며, 가장 효율적이고 직관적인 패턴은 무엇인지 고민해보게 된다.
또 더 나은 혹은 새로운 디자인 패턴은 없을까? 하고 생각해보게 된다.
무엇을 사용해야 한다는 정답은 따로 없기에, 프로젝트와 가장 잘 어울리는 패턴 또는 아키텍쳐가 정답이지 않을까... 라는 생각을 한다.
'React.js' 카테고리의 다른 글
[React] Cross-Domain Request 시 set-cookie가 되지 않는 이슈 [Same-Site:Strict] (0) | 2023.01.10 |
---|---|
[CSS] position absolute 속성 없이 Footer를 바닥에 고정하려면? (0) | 2023.01.03 |
[React] Ant Design DatePicker(RangePicker)와 Moment.js를 사용한 날짜별 필터링 기능 구현 (0) | 2022.09.29 |
[React] React-Query useMutation Hook 사용 시 비동기 처리Issue (0) | 2022.09.23 |
[React] Safari 환경에서 테스트 시 Select Box Option 텍스트가 노출 안되는 이슈 (0) | 2022.09.01 |