Skip to content

Conversation

@JaeHyunGround
Copy link

@JaeHyunGround JaeHyunGround commented Dec 9, 2025

배포 링크 : https://jaehyunground.github.io/front_7th_chapter3-3/

과제 체크포인트

기본과제

목표 : 전역상태관리를 이용한 적절한 분리와 계층에 대한 이해를 통한 FSD 폴더 구조 적용하기

  • 전역상태관리를 사용해서 상태를 분리하고 관리하는 방법에 대한 이해
  • Context API, Jotai, Zustand 등 상태관리 라이브러리 사용하기
  • FSD(Feature-Sliced Design)에 대한 이해
  • FSD를 통한 관심사의 분리에 대한 이해
  • 단일책임과 역할이란 무엇인가?
  • 관심사를 하나만 가지고 있는가?
  • 어디에 무엇을 넣어야 하는가?

체크포인트

  • 전역상태관리를 사용해서 상태를 분리하고 관리했나요?
  • Props Drilling을 최소화했나요?
  • shared 공통 컴포넌트를 분리했나요?
  • shared 공통 로직을 분리했나요?
  • entities를 중심으로 type을 정의하고 model을 분리했나요?
  • entities를 중심으로 ui를 분리했나요?
  • entities를 중심으로 api를 분리했나요?
  • feature를 중심으로 사용자행동(이벤트 처리)를 분리했나요?
  • feature를 중심으로 ui를 분리했나요?
  • feature를 중심으로 api를 분리했나요?
  • widget을 중심으로 데이터를 재사용가능한 형태로 분리했나요?

심화과제

목표: 서버상태관리 도구인 TanstackQuery를 이용하여 비동기코드를 선언적인 함수형 프로그래밍으로 작성하기

  • TanstackQuery의 사용법에 대한 이해
  • TanstackQuery를 이용한 비동기 코드 작성에 대한 이해
  • 비동기 코드를 선언적인 함수형 프로그래밍으로 작성하는 방법에 대한 이해

체크포인트

  • 모든 API 호출이 TanStack Query의 useQuery와 useMutation으로 대체되었는가?
  • 쿼리 키가 적절히 설정되었는가?
  • fetch와 useState가 아닌 선언적인 함수형 프로그래밍이 적절히 적용되었는가?
  • 캐싱과 리프레시 전략이 올바르게 구현되었는가?
  • 낙관적인 업데이트가 적용되었는가?
  • 에러 핸들링이 적절히 구현되었는가?
  • 서버 상태와 클라이언트 상태가 명확히 분리되었는가?
  • 코드가 간결하고 유지보수가 용이한 구조로 작성되었는가?
  • TanStack Query의 Devtools가 정상적으로 작동하는가?

최종과제

  • 폴더구조와 나의 멘탈모데일이 일치하나요?
  • 다른 사람이 봐도 이해하기 쉬운 구조인가요?

과제 셀프회고

폴더 구조

src/
  ├── app/                        # 앱 레벨 설정 및 전역 구성
  │   ├── providers/
  │   │   └── query-provider.tsx  # TanStack Query 프로바이더
  │   └── ui/
  │       ├── header.tsx          # 전역 헤더
  │       └── footer.tsx          # 전역 푸터
  │
  ├── shared/                     # 공통 모듈 (재사용 가능한 UI, 유틸리티)
  │   ├── api/
  │   │   └── http.ts            # Axios 인스턴스 설정
  │   ├── lib/
  │   │   ├── cn.ts              # 클래스네임 유틸리티
  │   │   └── highlight-text.tsx # 텍스트 하이라이트 유틸리티
  │   └── ui/                    # 공통 UI 컴포넌트
  │       ├── button/
  │       ├── card/
  │       ├── dialog/
  │       ├── input/
  │       ├── pagination/
  │       ├── select/
  │       ├── table/
  │       └── textarea/
  │
  ├── entities/                  # 비즈니스 엔티티 (타입, API, UI)
  │   ├── post/
  │   │   ├── api/
  │   │   │   └── post-api.ts    # 게시글 API 메서드
  │   │   ├── model/
  │   │   │   └── types.ts       # 게시글 타입 정의
  │   │   └── ui/
  │   │       ├── post-author.tsx    # 작성자 표시 컴포넌트
  │   │       ├── post-reactions.tsx # 반응 표시 컴포넌트
  │   │       └── post-tags.tsx      # 태그 표시 컴포넌트
  │   │
  │   ├── comment/
  │   │   ├── api/
  │   │   │   └── comment-api.ts
  │   │   ├── model/
  │   │   │   └── types.ts
  │   │   └── ui/
  │   │       ├── comment-item.tsx   # 개별 댓글 컴포넌트
  │   │       └── comment-list.tsx   # 댓글 목록 컴포넌트
  │   │
  │   ├── user/
  │   │   ├── api/
  │   │   │   └── user-api.ts
  │   │   └── model/
  │   │       └── types.ts
  │   │
  │   └── tag/
  │       ├── api/
  │       │   └── tag-api.ts
  │       └── model/
  │           └── types.ts
  │
  ├── features/                  # 사용자 액션 및 기능
  │   ├── post/
  │   │   ├── add-post/
  │   │   │   ├── model/
  │   │   │   │   ├── use-add-post-dialog.ts  # 다이얼로그 상태 관리
  │   │   │   │   └── use-add-post.ts         # 게시글 추가 로직
  │   │   │   └── ui/
  │   │   │       └── add-post-form.tsx       # 게시글 추가 폼
  │   │   │
  │   │   ├── edit-post/
  │   │   │   ├── model/
  │   │   │   │   ├── use-edit-post-dialog.ts
  │   │   │   │   └── use-edit-post.ts
  │   │   │   └── ui/
  │   │   │       ├── edit-post-button.tsx
  │   │   │       └── edit-post-form.tsx
  │   │   │
  │   │   ├── delete-post/
  │   │   │   ├── model/
  │   │   │   │   └── use-delete-post.ts
  │   │   │   └── ui/
  │   │   │       └── delete-post-button.tsx
  │   │   │
  │   │   ├── posts-list/
  │   │   │   └── model/
  │   │   │       └── use-posts-list.ts       # 게시글 목록 조회
  │   │   │
  │   │   └── view-post-detail/
  │   │       └── model/
  │   │           └── use-post-detail-dialog.ts
  │   │
  │   ├── comment/
  │   │   ├── add-comment/
  │   │   │   ├── model/
  │   │   │   │   ├── use-add-comment-dialog.ts
  │   │   │   │   └── use-add-comment.ts
  │   │   │   └── ui/
  │   │   │       └── add-comment-form.tsx
  │   │   │
  │   │   ├── edit-comment/
  │   │   │   ├── model/
  │   │   │   │   ├── use-edit-comment-dialog.ts
  │   │   │   │   └── use-edit-comment.ts
  │   │   │   └── ui/
  │   │   │       └── edit-comment-form.tsx
  │   │   │
  │   │   ├── delete-comment/
  │   │   │   └── model/
  │   │   │       └── use-delete-comment.ts
  │   │   │
  │   │   ├── like-comment/
  │   │   │   └── model/
  │   │   │       └── use-like-comment.ts
  │   │   │
  │   │   └── comments-list/
  │   │       └── model/
  │   │           └── use-comments-list.ts
  │   │
  │   ├── user/
  │   │   ├── user-detail/
  │   │   │   └── model/
  │   │   │       ├── use-user-detail-dialog.ts
  │   │   │       └── use-user-detail.ts
  │   │   │
  │   │   └── users-list/
  │   │       └── model/
  │   │           └── use-users-list.ts
  │   │
  │   └── tag/
  │       └── tags-list/
  │           └── model/
  │               └── use-tags-list.ts
  │
  ├── widgets/                   # 복합 UI 블록 (features + entities 조합)
  │   ├── posts-table/
  │   │   └── ui/
  │   │       ├── posts-table.tsx        # 게시글 테이블 전체
  │   │       ├── post-table-row.tsx     # 테이블 행
  │   │       └── posts-filter-bar.tsx   # 필터/검색 바
  │   │
  │   ├── post-detail-modal/
  │   │   └── ui/
  │   │       └── post-detail-modal.tsx  # 게시글 상세 모달
  │   │
  │   └── user-detail-modal/
  │       └── ui/
  │           └── user-detail-modal.tsx  # 사용자 상세 모달
  │
  └── pages/                     # 페이지 레벨 컴포넌트
      └── posts-manager-page.tsx # 게시글 관리 페이지

FSD 분리 기준

  • app : 전역 설정
  • page : page 단위
  • widgets : 큰 UI or 기능 단위
  • features : 비즈니스 동작을 수행하는 로직, 상태 관리
  • entities : 순수 api 호출 함수, 데이터 출력 ui
  • shared : 전역으로 쓰이는 요소 (컴포넌트, 유틸 함수 등)

위와 같이 FSD 분리 기준을 잡고 과제를 진행했습니다.

과제를 진행하면서 어려웠던 부분은 entitiesfeatures 의 분리 기준이 적절한지? 로직을 분리하면서도 어느 레이어에 넣어야하지 와 같은 고민을 반복적으로 하게 됐습니다.
저만의 분리 기준을 세웠음에도 불구하고 모호함의 영역이 해소되지 않았던 점이 답답하면서도 모호한 기준을 가지고 고민하는 과정을 거쳐가면서 어느정도 가닥이 잡혀가는 것이 흥미로웠습니다.
완벽한 FSD 분리 기준을 세우지는 못했지만, 레이어를 구분 함으로써 단방향 참조를 신경쓰고 명확한 폴더 구조를 잡아 가는 것에 대한 중요성을 느낄 수 있었습니다.

이번 과제를 통해 이전에 비해 새롭게 알게 된 점이 있다면 적어주세요.

FSD 분리 기준에 대해서 생각해볼 수 있었습니다. 이전에 회사 업무에 FSD를 도입해 본 경험이 있습니다. FSD를 처음 접해봤기도 했고, 팀원들 간 분리 기준에 대해 상이했던 부분이 많아 결국 폴더 구조가 엉망진창이 되었던 기억이 납니다.

이전까지 모호했던 레이어 - 슬라이스 - 세그먼트 의 개념에 대해서 이해할 수 있었고, 이전에 FSD를 도입했을 때 문제점이 무엇이었으며, 다음 프로젝트에선 어떻게 FSD를 도입해볼 지 고민해볼 수 있었습니다.

본인이 과제를 하면서 가장 애쓰려고 노력했던 부분은 무엇인가요?

다른 사람이 봤을 때 이해하기 쉬운 폴더 구조를 가져가고자 노력했습니다.

처음에는 CRUD 중에 R(useQuery)을 entities 레이어에, 나머지(useMutation)는 features 레이어에 두려다가 CRUD 기능을 분리하여 관리하는 것이 어색하다 생각해서 entities 레이어에 api 함수를, features 레이어에 useQuery, useMutation 로직을 넣어도 보고,
단순 데이터를 props로 받아 view의 역할만 하는 ui는 entities, 데이터의 변화을 일으키는 ui 요소는 features 레이어로 분리도 해보면서
많은 분들이 헷갈려했던 entities, features 레이어에는 각각 어떤 로직들이 들어가야 할까? 에 대해 한 가지 방향성을 제시할 수 있을만한 폴더 구조를 짜고자 노력했던 것 같습니다.

아직은 막연하다거나 더 고민이 필요한 부분을 적어주세요.

  • features vs entities 분리 기준
  • widgets 에는 어떤 코드들이 들어가야 하는지
  • entities, features의 슬라이스 에는 도메인 네이밍이, widgets의 슬라이스에는 UI 요소의 이름을 작성했는데 올바른 방법일지
    • ex) /entities/post/ui/post-tag.tsx 와 /widgets/posts-table/ui/post-table-row.tsx

이번에 배운 내용 중을 통해 앞으로 개발에 어떻게 적용해보고 싶은지 적어주세요.

회사 업무에 FSD를 재적용하여 성공적인 FSD 도입 사례를 남겨보고 싶습니다.

팀원 간 폴더 구조 컨벤션을 명확히 하고 이를 문서화하여 팀원 간 생각의 차이가 많이 나지 않도록 하고, 커뮤니케이션 비용을 줄여 빠른 생산성을 직접적으로 느껴보고 싶습니다.

챕터 셀프회고

클린코드와 아키테쳑 챕터 함께 하느라 고생 많으셨습니다!
지난 3주간의 여정을 돌이켜 볼 수 있도록 준비해보았습니다.
아래에 적힌 질문들은 추억(?)을 회상할 수 있도록 도와주려고 만든 질문이며, 꼭 질문에 대한 대답이 아니어도 좋으니 내가 느꼈던 인사이트들을 자유롭게 적어주세요.

클린코드: 읽기 좋고 유지보수하기 좋은 코드 만들기

  • 더티코드를 접했을 때 어떤 기분이었나요? ^^; 클린코드의 중요성, 읽기 좋은 코드란 무엇인지, 유지보수하기 쉬운 코드란 무엇인지에 대한 생각을 공유해주세요

코드가 눈에 안 들어오고, 서비스의 기능은 어떤 것이며 어디까지 특정 함수에 대한 로직인지 파악이 잘 안됐습니다. 코드를 보자마자 들었던 생각은 아..... 였던 것 같네요 ㅎㅎ

클린코드를 작성해야 하는 이유는 내가 아닌 다른 사람이 작성한 코드를 볼 때 이해하기 쉽게 하기 위함이라고 생각합니다. 개발은 혼자 보단 여러 사람과 협업을 하는 경우가 훨씬 많고, 코드 구조를 구상하고 작성하는 시간보다 이 코드는 무슨 역할을 하는 코드지? 라는 생각을 더 많이 하게 되는 순간 커뮤니케이션 비용도 비싸지고 결국에는 효율성이 떨어지는 상태가 지속될 것이라고 생각합니다.

따라서 클린 코드를 작성함으로써 팀원간 커뮤니케이션 비용을 줄이고, 전반적인 코드 스타일을 맞추어 같은 서비스 내의 코드에서도 이질감이 느껴지지 않게 하며, 코드를 이해하기 위해 많은 노력을 기울이지 않아도 되는 상황을 만드는 것이 이상적인 협업 과정이라고 생각했습니다 !

결합도 낮추기: 디자인 패턴, 순수함수, 컴포넌트 분리, 전역상태 관리

  • 거대한 단일 컴포넌트를 봤을때의 느낌! 처음엔 막막했던 상태관리, 디자인 패턴이라는 말이 어렵게만 느껴졌던 시절, 순수함수로 분리하면서 "아하!"했던 순간, 컴포넌트가 독립적이 되어가는 과정에서의 깨달음을 들려주세요

컴포넌트를 분리함으로써 컴포넌트의 재사용성을 늘리고, 계산 로직은 utils의 개념으로 액션 로직은 hooks의 개념으로 분리해보며 역할에 따라 명확하게 코드를 분리했을 때 가져오는 이점에 대해 체감할 수 있었습니다. (이점 : 관심사가 분리되어 원하는 로직을 빠르게 찾을 수 있다, 비즈니스 로직과 UI 로직을 분리함으로써 각 코드가 집중해야 할 부분을 명확히 함으로써 코드 가독성이 높아진다.)

응집도 높이기: 서버상태관리, 폴더 구조

  • "이 코드는 대체 어디에 둬야 하지?"라고 고민했던 시간, FSD를 적용해보면서의 느낌, 나만의 구조를 만들어가는 과정, TanStack Query로 서버 상태를 분리하면서 느낀 해방감(?)등을 공유해주세요

다음에 FSD를 사용한다면 entities, features 레이어를 통합해서 써볼 수 있을 것 같고, widgets의 분리 기준을 명확히 할 수 있다면 지금보다 더 적절한 폴더구조를 가져갈 수 있을 것이라 생각했습니다.

폴더 구조를 짤 때 이전까진 남들이 했던 방법대로 따라했던 경우가 많았는데, 레이어 분리에 대한 저만의 기준을 세우고 그 기준에 따라 코드를 분리하는 경험을 함으로 인해 개발자로써 줏대(?)가 조금은 생긴 것 같습니다. ㅎ.ㅎ

리뷰 받고 싶은 내용이나 궁금한 것에 대한 질문

코치님의 FSD 레이어 분리 기준

많은 분들께 여쭤봤을 때 FSD 레이어를 분리하는 기준이 다른 경우가 많았어서 흥미로웠습니다. 코치님께서는 프로젝트에서 FSD를 도입하신다고 하면 어떤 기준을 가지고 레이어를 분리하실 것인지, 슬라이스(도메인)은 어떤 기준으로 나눌 것 같으신지 궁금합니다 !

entities, features의 슬라이스 에는 도메인 네이밍이, widgets의 슬라이스에는 UI 요소의 이름을 작성했는데 올바른 방법일지 궁금합니다 !

  • /entities/post/ui/post-tag.tsx
  • /widgets/posts-table/ui/post-table-row.tsx

와 같이 entities 슬라이스는 도메인 네이밍, widgets 슬라이스는 UI 네이밍을 작성했는데 올바른 방법인지 궁금해요...!!

- 전역 레이아웃을 담당하는 요소라고 판단하여 app 레이어에 배치했습니다.
기존 /components/index.tsx 에 있던 컴포넌트 무더기 코드를 shared 레이어 ui 세그먼트로 분리했습니다.
- api 호출 로직
- 타입
을 entities 레이어에 생성했습니다.
- api 호출 로직
- 타입
을 entities 레이어에 생성했습니다.
- api 호출 로직
- 타입
을 entities 레이어에 생성했습니다.
- api 호출 로직
- 타입
을 entities 레이어에 생성했습니다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant