[10팀 홍혜원] Chapter 2-3. 관심사 분리와 폴더구조#68
Open
Wonny-ing wants to merge 19 commits intohanghae-plus:mainfrom
Open
Conversation
…comment 관련 API 호출 로직을 별도의 서비스 파일 생성
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
과제 체크포인트
https://wonny-ing.github.io/front_5th_chapter2-3/
기본과제
목표 : 전역상태관리를 이용한 적절한 분리와 계층에 대한 이해를 통한 FSD 폴더 구조 적용하기
체크포인트
심화과제
목표: 서버상태관리 도구인 TanstackQuery를 이용하여 비동기코드를 선언적인 함수형 프로그래밍으로 작성하기
체크포인트
과제 셀프회고
이번 프로젝트의 목표 중 하나는 효과적인 상태 관리와 코드 구조화였습니다. 기존 코드는 하나의 컴포넌트에서 너무 많은
useState를 사용하고 있었고 그로 인해 코드가 점점 복잡한 상태였습니다.가장 첫번째로 한 작업은 관심사에 따라 컴포넌트를 나누는 것이었습니다.
이때 가장 고민했던 부분은 바로
👉 “상태를 어떻게 분리하고, 어떤 계층 구조로 관리할 것인가”였습니다.
단순히 전역 상태 관리 라이브러리를 도입하는 것보다, 상태의 성격에 따라 적절히 나누고, 각 계층의 책임을 명확히 정의하는 것이 더 중요하다고 느꼈습니다.
그래서 이번에는 FSD 아키텍처를 기반으로 상태를 어떻게 나눌지, 어떤 기준으로 관리할지를 중점적으로 고민했습니다.
👾 기존 상태 관리의 문제점
기존 코드는 PostManager 컴포넌트안에서 모든 상태를 useState를 통해 관리하고 있었습니다.
이처럼 하나의 컴포넌트에서 너무 많은 상태를 관리하다 보니, 아래와 같은 문제들이 생겼습니다:
이런 문제들을 해결하기 위해, 상태 관리 전략을 다시 설계했습니다.
핵심은
관심사 분리(Separation of Concerns)였고, 다음과 같은 기준을 가지고 리팩토링을 진행했습니다:리팩토링 접근 방식과 기준
1. 서버 상태와 클라이언트 상태의 명확한 구분
가장 먼저 했던 일은 상태를 두 가지로 나누는 것이었습니다:
서버 상태: 서버에서 가져오는 데이터 (예: 게시글 목록, 댓글, 사용자 정보 등)
→
TanStack Query로 관리클라이언트 상태: UI에서만 의미 있는 상태 (예: 모달 열림 여부, 현재 선택된 항목 등)
→
Zustand로 관리이렇게 구분한 이유는 단순히 기술적인 이유 때문만은 아닙니다!
각 상태는 성격이 완전히 다르기 때문이에요:
서버 상태 (
TanStack Query)클라이언트 상태 (
Zustand)도메인 기반 모듈화
상태를 단순히 기능이나 화면 기준으로 나누는 대신, 도메인 엔티티(Entity) 중심으로 구조화를 했습니다.
즉, 게시물, 댓글, 사용자처럼 실제 비즈니스 개념 을 기준으로 모듈을 나눴습니다!
features/ post/ model/ types.ts // 타입 정의 store.ts // Zustand로 클라이언트 상태 관리 api/ queries.ts // TanStack Query로 서버 상태 관리이렇게
Comment나User도메인도 동일한 방식으로 구조화하니까 관련 로직이 한 폴더에 모이면서도 깔끔하게 분리되고 재사용성도 좋아졌습니다.화면 전용 UI(Layout) 상태 분리
UI 상태는 별도 스토어로 분리했습니다.
이렇게 하니까 전역 스토어를 오염시키지 않으면서도, UI 로직을 깔끔하게 관리할 수 있게 되어 컴포넌트가 깔끔해졌습니다!
서버 상태 vs 클라이언트 상태 구분 기준
TanStack Query로 관리하는 서버 상태
서버에서 오는 데이터를 기반으로 하고, 다음과 같은 특성을 가지면
서버 상태(Server State)로 보고 TanStack Query로 관리했습니다.📌 예시
usePostsQuery)useCommentsQuery)useUserQuery)Zustand로 관리하는 클라이언트 상태
아래 기준에 부합하는 경우는 클라이언트 상태로 보고 Zustand에서 관리했습니다:
📌 예시
selectedPost)filters)UI 상태 vs 도메인 상태 구분
클라이언트 상태(Zustand) 안에서도 또 나눴어요:
👉 UI 상태 vs 도메인 상태
UI 상태 (LayoutStore)
순수 UI를 위한 상태는 도메인 상태와 분리된 전용 스토어로 만들었습니다.
그 이유는 전역 도메인 스토어를 더럽히지 않기 위해서 입니다.
UI 상태는 단순히 시각적 표현만을 위해 존재하는 상태이기 때문에, Zustand 내에서도 별도 스토어 파일 로 분리하여 관리했습니다!
도메인 상태 (Entity 중심)
게시물, 댓글, 사용자처럼 실제 도메인 모델과 연관된 상태는 전용 도메인 스토어에서 관리했습니다.
이런 도메인 스토어는 UI와 독립적으로 테스트 가능해야 한다는 기준도 있었어요!
이렇게 최상위 컴포넌트에서 관리하던 useState를 Zustand와 TanStack Query 기반의 체계적인 상태 관리 구조로 리팩토링하면서, 단순히 상태 관리 라이브러리를 바꾼 게 아니라 애플리케이션 아키텍처 자체를 재설계하는 계기가 되었습니다. 서버 상태와 클라이언트 상태를 명확하게 나누고, 도메인 중심으로 상태와 로직을 모듈화하면서 유지보수성과 확장성이 훨씬 좋아진거 같다고 느꼈어요.
이번 리팩토링을 통해 “상태를 어디에 저장할지”에 대한 고민이 단순한 기술 선택이 아니라 전체 구조와 개발 경험에 영향을 주는 중요한 결정이라는 걸 다시 한번 느꼈습니다!
아직도 잘 모르겠는 부분
features 디렉토리에서 CRUD 관련 컴포넌트들을 따로 분리하긴 했는데, 이미 API 관련 로직들은 대부분 entities 쪽에 정리돼 있어서 어떤 API 로직을 어디에 두는 게 맞는지 명확하게 판단하기 어려웠어요. 예를 들어 entities/post/api/addPost처럼 이미 존재하는 함수가 있는 상황에서, 같은 기능을 features/post/api에도 둬야 하는지, 혹은 옮겨야 하는지 애매하더라고요.
사실 개인적으로는 entities 폴더 하나만 가지고 도메인 기준으로 잘 나눠놓으면 그걸로 충분하다고 느꼈고, 오히려 그게 더 관리하기 편하다고 생각했어요. 이번엔 과제 조건에 맞춰서 features로 나눴지만, 없었으면 그냥 entities 안에서만 관리했을 것 같아요.