React 개발하면서 폴더구조에 대하여 깊이 생각하지 않았고, 유용하게 쓰이는 대로 사용해 보았는데, 왜 이렇게 사용하지에 대한 의문이 들었다. 그래서 이 섹션을 적게 되었습니다.
Flutter로 개발을 할 때, 아키텍처 패턴에 대해 고민해본 적이 있었다. 특히 MVC, MVP, MVVM에 대해 많이 생각했었습니다. 그중에서도 MVVM은 많은 사람들이 M (Model), V (View), VM (ViewModel)을 비슷하게 생각하지만, 실제로 각 부분을 어떻게 맞추는지가 조금씩 달라서 그 부분을 맞춰가는 과정이 정말 중요하다고 느꼈습니다.
아키텍처 패턴(Architecture)이란?
- 주어진 상황에서의 소프트웨어 아키택처에서 일반적으로 발생하는 문제점들에 대한 일반화되고 재사용 가능한 솔루션이다. 아키택쳐 패턴은 소프트웨어 디자인 패턴과 유사하지만 더 큰 범주에 속합니다.
- 아키택처 패턴의 종류와 갯수는 정해져 있지 않으며, 새로운 패턴이 등장하기도 합니다.
React에서의 아키택처 패턴의 진화
React의 아키텍처 패턴은 시간이 지남에 따라 점차 발전해왔습니다. 각각의 패턴은 특정 문제를 해결하기 위한 노력의 결과이며, 상태 관리와 데이터 흐름을 어떻게 효율적으로 처리할지에 대한 고민에서 발전하였습니다. 아래는 React에서 주요 아키텍처 패턴이 어떻게 진화해왔는지에 대한 개요입니다.
1. MVC (Model-View-Controller)
- 초기 아키택처 패턴으로, 데이터를 Model에서 관리하고, View에 데이터를 표시하며, Controller가 이벤트를 처리하는 방식입니다.
- React에서는 이 구조가 컴포넌트로 분리되지만, React 자체가 View에 집중하므로 MVC는 React 개발에서 그다지 적합하지 않았습니다.
2. MVVM (Model-View-ViewModel)
- ViewModel은 UI 로직과 상태를 관리하고, View는 UI 렌더링하는 역할을 합니다.
- React에서 MVVM 패턴은 주로 컴포넌트가 View 역할을 하고, useState, useEffect와 같은 훅을 활용하여 ViewModel 역할을 하며, props나 Context API로 Model을 관리합니다.
3. Component-based Architecture
- React의 컴포넌트 기반 아키텍처는 MVC나 MVVM을 넘어서 모든 UI를 컴포넌트로 분리하여 관리하는 방식입니다. UI와 상태 로직을 한 곳에서 처리할 수 있기 때문에, React의 기본적인 아키텍처라고 할 수 있습니다.
4. Container-Presenter Pattern
- Container-Presenter 패턴은 컴포넌트를 두 가지 역할로 나누는 방법입니다.
- Container 컴포넌트는 상태를 관리하고, 데이터를 로딩하며, 이벤트 처리를 담당합니다.
- Presenter 컴포넌트는 UI만 담당하고, props를 통해 데이터를 전달받습니다
- 이 방식은 컴포넌트의 역할을 명확히 분리하여 가독성을 높이고, 컴포넌트의 재사용성을 높이는 데 유용합니다.
5. Flux
- Flux는 Facebook이 제안한 아키텍처로, 단방향 데이터 흐름을 강조합니다. Action, Dispatcher, Store, View의 구조로 이루어져 있습니다.
- Flux는 상태의 예측 가능성과 데이터 흐름을 관리하기 용이하게 만들어졌습니다.
- 하지만 보일러플레이트 코드가 많고, 관리가 복잡해질 수 있다는 단점이 있었습니다.
6. Redux
- Redux는 Flux를 간소화한 상태 관리 라이브러리입니다. 애플리케이션의 상태를 단일 상태 트리로 관리하며, 액션을 통해 상태를 업데이트하고, 리듀서가 상태 변화를 처리합니다.
- Redux는 상태를 중앙에서 관리하고, 컴포넌트 간의 상태 공유를 쉽게 하며, 예측 가능한 상태 관리를 제공합니다.
- 하지만 보일러플레이트 코드가 많고, 복잡한 상태 관리를 할 때 Redux-thunk나 Redux-Saga 등을 추가로 사용해야 했습니다.
7. MobX
- MobX는 반응형 상태 관리 라이브러리로, 상태의 변화에 따라 UI가 자동으로 업데이트됩니다. 상태의 변경을 자동 추적하여 효율적인 상태 관리를 제공합니다.
- MobX는 상대적으로 간단하고 직관적이며, Redux에 비해 보일러플레이트 코드가 적고, 빠른 학습 곡선을 가집니다. 그러나 대규모 애플리케이션에서는 관리가 어려울 수 있습니다.
8. Context API
- React의 Context API는 애플리케이션 전체에서 전역 상태를 쉽게 관리할 수 있게 해주는 기능입니다. 이를 통해 컴포넌트 트리 깊숙한 곳까지 props를 전달할 필요 없이, 필요한 곳에서 바로 상태를 사용할 수 있습니다.
- 작은 프로젝트나 상태가 그리 복잡하지 않은 경우 Context API는 유용하지만, 상태가 복잡해지면 성능 문제나 컴포넌트의 과도한 재렌더링을 유발할 수 있습니다.
9. React Hooks
- React Hooks는 함수형 컴포넌트에서 상태 관리와 부수 효과(side effects)를 처리할 수 있도록 해주는 기능입니다.
- useState, useEffect, useContext, useReducer 등이 있으며, 훅을 사용하면 컴포넌트 내에서 로직을 재사용할 수 있습니다.
- Hooks는 클래스 컴포넌트의 복잡성을 없애고, 함수형 컴포넌트로 더 직관적이고 깔끔한 코드를 작성할 수 있게 해줍니다.
10. React-Query
- React-Query는 서버 상태를 관리하기 위한 라이브러리로, 데이터 페칭, 캐싱, 동기화, 에러 처리 등을 관리할 수 있습니다.
- API와 관련된 데이터 관리에서 발생하는 복잡성을 해결해주며, 서버와의 데이터 통신을 더 효율적으로 처리할 수 있게 돕습니다.
11. Zustand
- Zustand는 React 상태 관리를 간소화한 라이브러리로, 간단한 API와 직관적인 상태 관리를 제공합니다. 이 라이브러리는 경량화된 상태 관리 도구로, 복잡한 애플리케이션에서 Redux보다 더 유연하고 빠른 속도를 자랑합니다.
- 상태 관리와 컨텍스트를 분리할 수 있으며, 필요한 상태만 간단히 업데이트할 수 있습니다.
12. Recoil, Jotail, Valtio
- 이들 라이브러리는 React 상태 관리의 새로운 접근을 제공합니다. 각 라이브러리는 조금씩 다르지만, 핵심은 원자적 상태 관리입니다.
- Recoil: 비동기 상태와 상태 관계 관리를 잘 지원하며, 상태의 의존성을 효율적으로 관리합니다.
- Jotai: 원자적 상태 관리를 제공하며, 간단한 API로 빠르고 효율적인 상태 관리를 지원합니다.
- Valtio: 프록시 기반의 상태 관리로, 상태 객체를 직접 수정하면서 간단하고 직관적인 상태 관리를 제공합니다.
13. 결론
React의 아키텍처 패턴은 상태 관리와 데이터 흐름을 다루는 다양한 솔루션들이 점진적으로 진화하면서 발전해왔습니다. 각 패턴은 애플리케이션의 규모, 복잡성, 필요성에 맞춰 선택할 수 있으며, 기술의 발전과 개발자의 요구에 따라 점차 효율적이고 간결한 방식으로 바뀌었습니다
React에서 지금 가장 많이 쓰이는 폴더 구조는 어떤 것이 있을까?
1. 기본적인 폴더구조
/src
/assets // 이미지, 폰트 등 리소스
/components // 재사용 가능한 컴포넌트들
/pages // 각 페이지를 담당하는 컴포넌트들
/services // API 호출, 서비스 로직 등을 처리하는 폴더
/store // 상태 관리 (예: Redux, Context API)
/utils // 유틸리티 함수들
/styles // 공통 스타일 파일들
App.js // 애플리케이션의 최상위 컴포넌트
index.js // 진입점
- 여러 가지 표준적인 폴더 구조들이 존재하지만, 그중에서도 많이 사용되는 구조는 위와 같다
2. 컴포넌트 기반 구조
/src
/components
/Button
Button.js
Button.css
Button.test.js
/Input
Input.js
Input.css
Input.test.js
- React의 강력한 컴포넌트 기반 아키택처를 최대한 활용하는 구조
- 컴포넌트 단위로 나누어서 코드의 재사용성과 관리 용이성을 높이는 방식이다.
3. 도메인 기반 구조
/src
/auth
/components
Login.js
Register.js
/services
authService.js
/dashboard
/components
Dashboard.js
/services
dashboardService.js
/profile
/components
Profile.js
/services
profileService.js
- 프로젝트의 기능별로 폴더를 나누어 관리하는 방식이다.
- 규모가 커지고 여러 기능이 추가 될 때 유용하게 사용할 수 있다.
- Next.js는 파일 기반 라우팅 시스템을 사용하는데 비슷한 구조인것 같다(Next는 프레임워크)
결론
폴더구조와 아키택처는 서로 영향을 주고받으면서 애플리케이션을 어떻게 잘 나누고 관리하는지를 결정하는 중요한 요소이기 때문에 프로젝트 환경에 맞게 유연하게 설정할 줄 알아야 한다.