본문으로 건너뛰기

Overview

우리 앱 아키텍처는 확장성, 유지보수성, 관심사의 분리와 같은 다양한 요구사항을 해결하기 위해 목적에 맞게 선택된 여러 디자인 패턴으로 구성되어 있습니다.

Core Concept

Handling State Management & Side Effects

핵심 상태 관리와 사이드 이펙트 처리를 위해 우리는 Redux 패턴을 따릅니다. 이 패턴은 Flux 개념을 기반으로 하지만, 단일 전역 저장소, 불변 상태 업데이트, 순수 리듀서 함수를 강조합니다. 이 아키텍처는 단방향 데이터 흐름을 촉진하여 애플리케이션의 동작을 예측 가능하게 만들고, 디버깅을 용이하게 하며, 테스트가 쉬운 구조를 제공합니다.

우리가 Redux를 선택한 이유는 **단일 진실의 원천(Single Source of Truth)**을 제공하여 디버깅을 단순화하고, 기능 전반에 걸쳐 일관성을 향상시키기 때문입니다. 이는 앱이 확장됨에 따라 특히 중요해집니다.

Separation of Concerns in Component Architecture

로직과 UI의 명확한 분리를 위해 우리는 VAC 패턴Compound Component 패턴을 함께 사용합니다.

  • VAC(View-Asset-Component 구조의 약어)는 VAC 컴포넌트가 순수 JSX 렌더러 역할을 하며 props 객체를 받아 렌더링하는 설계 관례를 의미합니다. 모든 로직, 상태, UI 동작은 외부(일반적으로 커스텀 훅)에서 처리되며, 컴포넌트는 오직 props를 기반으로 렌더링됩니다.
  • Compound Component PatternCard.Header, Card.Body와 같은 하위 컴포넌트를 사용하여 UI 컴포넌트를 구조화할 수 있도록 하여, 조합 가능성, 유연성, 디자인 일관성을 제공합니다.

Two Patterns Combined

이 두 가지를 결합함으로써 다음과 같은 장점이 있습니다:

  • 로직과 상태가 UI 렌더링으로부터 완전히 분리됩니다
  • 컴포넌트는 props 기반으로 선언적이며 테스트가 용이합니다
  • UI 구성은 재사용 가능한 슬롯 기반 API를 통해 유연하고 확장 가능합니다

이 접근 방식은 개발자와 디자이너가 독립적으로 협업할 수 있도록 하며, 확장 가능한 기능 개발을 지원하고, 코드베이스 전반에 걸쳐 깔끔하고 유지보수 가능한 아키텍처를 강화합니다.

A Bird's-eye view

우리 앱의 전체 흐름은 다음과 같습니다.

요소설명
ViewUI는 상태 변경 또는 사이드 이펙트를 트리거하기 위해 dispatch를 호출합니다.
Action이벤트를 설명하는 순수 객체입니다 (type, 선택적 payload 포함).
Middleware액션을 가로채 Saga로 처리하거나 Reducer로 전달합니다.
Redux-Saga선언적으로 비동기 사이드 이펙트를 관리하는 generator 기반 미들웨어입니다.
Side Effect TasksAPI 요청, SDK 메서드 호출 또는 초기화 등 외부 작업을 실행합니다.
Action (Result)사이드 이펙트 결과로 SUCCESS / FAILURE 등의 새 액션을 dispatch 합니다.
Reducer액션과 현재 상태를 기반으로 새로운 상태를 반환하는 순수 함수입니다.
Store애플리케이션의 상태를 저장하고 업데이트하는 중앙 상태 저장소입니다.
View (Re-render)Store의 상태가 변경되면 React UI가 자동으로 다시 렌더링됩니다.

Directory Structure

우리 앱의 디렉토리 구조는 다음과 같습니다

src/

├── apis/ # API 호출 정의 모음
│ # - axios/fetch 기반 요청 함수
│ # - 서비스 도메인별로 폴더 분리 (e.g., `account/`, `report/`)

├── assets/ # 정적 리소스 관리
│ # - 이미지, GIF, SVG, Lottie JSON 등


├── CDS/ # 디자인 시스템 및 공통 컴포넌트 (Connecting Design System)
│ # - Button, Input, Modal 등 재사용 가능한 UI 컴포넌트
│ # - 내부적으로 스타일과 상태 분리 가능

├── globals/ # 전역 상수 및 설정 값
│ # - 전역 ENV 설정, 스타일 상수 (colors, spacing 등)
│ # - 언어 파일, 에러 메시지 등도 포함 가능

├── interfaces/ # 비즈니스 도메인 타입 및 인터페이스
│ # - API 응답 타입, Redux 상태 타입 등 정의
│ # - 도메인별 폴더 분리 권장 (account/, report/)

├── navigator/ # 네비게이션 관련 설정
│ # - React Navigation stack/switch/tab 구성
│ # - 네비게이터 간 공통 설정 및 route types

├── pages/ # 실제 화면 단위 컴포넌트
│ # - Home, Login, Settings 등 페이지별 디렉토리
│ # - 각 디렉토리 내에서 `index.tsx`, `hooks/`, `components/` `systems/` 등으로 구조화 가능

├── reducers/ # Redux reducer 정의
│ # - 도메인별 reducer 관리 (e.g., account.ts, appState.ts)


├── sagas/ # Redux-Saga 관련 비동기 로직
│ # - 비동기 flow 및 API side-effect 처리
│ # - watcher/worker 구조 권장

├── selectors/ # Reselect 기반 상태 추출 로직
│ # - 도메인 상태를 가공하여 필요한 형태로 반환
│ # - 성능 최적화를 위해 memoization 적용

├── system/ # 시스템 레벨 로직 또는 모듈
│ # - 모달 컴포넌트, 앱 전역에 영향을 주는 컴포넌트


└── utils/ # 유틸리티 함수 모음
# - 문자열 처리, 날짜 포맷, 디바운스 등 재사용 로직
# - 테스트 가능한 pure function 위주로 구성