배포 링크
https://annkimm.github.io/front_6th_chapter2-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가 정상적으로 작동하는가?
최종과제
- 폴더구조와 나의 멘탈모데일이 일치하나요?
- 다른 사람이 봐도 이해하기 쉬운 구조인가요?
과제 셀프회고
- 이번 과제는 금요일에 휴일이라서 월화수를 좀 날려먹은 감이 없지 않아 있어서 금요일 새벽 7시까지 달렸다.
- 월화수까지는 대부분을 내가 관여하고 짰는데 목요일에 리액트쿼리 바꾸는 부분부터 클로드가 힘내길 바랬다. 다행히 ^.^ 클로드가 한번도 한도 초과하지 않아서 잘 마무리하였다.
이번 과제를 통해 이전에 비해 새롭게 알게 된 점이 있다면 적어주세요.
- 엔티티에 어떤 UI에 들어가야하는지 잘 이해가 안갔는데 readoly 한 UI는 들어갈 수 있다는걸 알게 되었습니다. 그래서 엔티티에 UI는 사실 하나도 들어가지 않았습니다. 사실상 개인적인 생각으로는 feature에서 따로 UI로 만들어도 생각없지 않나 라는 판단하였습니다. 그게 맞는지는 잘 모르겠지만 그런 생각이 들었습니다.
본인이 과제를 하면서 가장 애쓰려고 노력했던 부분은 무엇인가요?
이번에 세운 폴더구조
- 어떤 프로젝트를 하던지 간에 폴더 구조를 어떻게 잡을지가 가장 고민이 되었습니다. 생각으로는 폴더 구조는 한 번 정착하고 나면 그뒤에 바꾸는게 큰 비용을 유발하기 때문에 초반부터 잘 정착해야 된다고 생각했기 때문에 어떤 구조를 가야할까. 가장 고민스러웠던 부분은 dialog쪽과 엔티티는 4개로 나눴는데 feature 또한 4개의 폴더로 나눠야할까? 싶었습니다. 그래서 고민을 하다가 feature은 인터렉션을 하는 기능 중심의 폴더라는 생각이 들어서 간단한 user나 tag의 경우에는 나눌 필요까지는 없겠다 싶었습니다. 어짜피 post 안에 들어가도 무난한 크기라고 생각했습니다.
- dialog쪽도 고민이었던 이유는 dialog 중에 'PostUserDialog'는 리스트에서 글을 클릭해서 확인했을 때 댓글이 들어가는 부분이 있어서, 근데 이부분은 commnet를 더 크게 봐야할까 아니면 post로 속해야할까 잘 판단이 되지 않는 부분이었는데 어쨋든 이 dialog는 이 글을 클릭했을 때 나오는게 주요적인 기능이라는 판단하게 post에 그대로 냅두도록 하였습니다.
아직은 막연하다거나 더 고민이 필요한 부분을 적어주세요.
- 이번 과제 말고 다른 프로젝트에서 fsd를 해볼때 shared -> entities -> widget -> feature -> page 순으로 하여 widget과 feature을 바꿔서 작업한 적이 있습니다. 뭔가 widget은 독립적이지만 컴포넌트라는 부분에서 feature에 가져와서 사용하게 되더라구요. 이게 원래 FSD와는 맞지 않는 기본 원칙같아서 프로젝트를 하면서도 내내 찜찜한 느낌이 없지 않아서 아직 widget에 대한 개념이 부족한가 싶기도 합니다.
이번에 배운 내용 중을 통해 앞으로 개발에 어떻게 적용해보고 싶은지 적어주세요.
- react-query에 대해 키를 관리하거나. mutation?을 아직 프로젝트에 적용해본 적이 거의 없어서 이런 걸 실제 사용해보는 사례를 만들어 보고 싶습니다.
챕터 셀프회고
클린코드와 아키테쳑 챕터 함께 하느라 고생 많으셨습니다! 지난 3주간의 여정을 돌이켜 볼 수 있도록 준비해보았습니다. 아래에 적힌 질문들은 추억(?)을 회상할 수 있도록 도와주려고 만든 질문이며, 꼭 질문에 대한 대답이 아니어도 좋으니 내가 느꼈던 인사이트들을 자유롭게 적어주세요.
클린코드: 읽기 좋고 유지보수하기 좋은 코드 만들기
- 더티코드를 접했을 때 어떤 기분이었나요? ^^; 클린코드의 중요성, 읽기 좋은 코드란 무엇인지, 유지보수하기 쉬운 코드란 무엇인지에 대한 생각을 공유해주세요
- 일단 시간은 한정되어 있고 더티 코드의 양은 너무 길고, 이걸 어떻게 핸들링할지 몰라서 AI한테 의존하는 시간이 너무 길었던 거 같습니다. 코드를 잘짜야한다는 것을 다시 한 번 느끼는 시간이었습니다. 그런 코드들을 실제로 실무에서 만나게 되면 아무래도 해석하는데도 시간이 너무 걸리고 그걸 가지고 만들어야할때도 코드가 더 더러워질꺼라는 생각이 들었습니다.
- 아무래도 함수가 단일 원칙을 가진 함수이면 일수록 유지보수나 읽기 좋은 코드일꺼라는 생각이 들었습니다. 어쨌든 핵심이 그 하나만 보면 되니까요. 하지만 단일 원칙을 따르지 않는다면 아무래도 분산이 되어 있어서 알아보기 힘든 코드가 될꺼라는 생각이 들었습니다.
결합도 낮추기: 디자인 패턴, 순수함수, 컴포넌트 분리, 전역상태 관리
- 거대한 단일 컴포넌트를 봤을때의 느낌! 처음엔 막막했던 상태관리, 디자인 패턴이라는 말이 어렵게만 느껴졌던 시절, 순수함수로 분리하면서 "아하!"했던 순간, 컴포넌트가 독립적이 되어가는 과정에서의 깨달음을 들려주세요
- 앞에 1주차 코드가 너무 길고 더티했던지라 이 단일 컴포넌트는 좀 할 맛이 났습니다. 왜냐면 단일 컴포넌트는 내가 나누기도 하고 모르는 부분에 대해서는 부분적으로 AI에게 물어봤으니까요.
- 도메인 함수와 유틸 함수에 대해서 나누는 기준을 잘 몰라서 질문하기까지 했는데, 그 함수가 공통적으로 전체적으로 쓰이는지 아니면 그 도메인에만 쓰인다면 도메인 함수라는 답을 얻고 좀 '아 유레카' 싶은 생각이 들었습니다.
응집도 높이기: 서버상태관리, 폴더 구조
- "이 코드는 대체 어디에 둬야 하지?"라고 고민했던 시간, FSD를 적용해보면서의 느낌, 나만의 구조를 만들어가는 과정, TanStack Query로 서버 상태를 분리하면서 느낀 해방감(?)등을 공유해주세요
- FSD를 하면서 느끼는 점은 UI는 어디에 두어야 좋을것인가를 항상 고민한다는 점이었습니다. UI는 어디에 두어도 들어갈수 있다는 점이었습니다. 하지만 여기서 고민해야할것은 UI와 함수는 보통 같이 움직여야하기 때문에 그와 같이 움직여야할때 편한 부분은 어딘가에 대해서 생각할 때 feature에서는 UI와 함수는 같이 움직일 있는 구조라는 생각이 들어서 많이 feature에 UI 폴더를 만들어서 작업하기도 했습니다.
- TanStack Query로 인한 해방감은 잘 모르겠지만, zustand에서 분리하여 post와 comment를 신경이 덜 써도 된다는 점은 좋은 점이었습니다.
리뷰 받고 싶은 내용이나 궁금한 것에 대한 질문
(적을 부분 추가)
과제 피드백
수고했습니다. 지난 3주간 클린코드를 비롯한 소프트웨어 공학적으로 결합도 낮추기 응집도 높이기를 위한 이론과 프론트엔드에서의 적용등을 통해서 좋은 코드와 구조에 대한 다각도의 시야가 생겼기를 기대합니다.
"엔티티에 어떤 UI에 들어가야하는지 잘 이해가 안갔는데 readoly 한 UI는 들어갈 수 있다는걸 알게 되었습니다. 그래서 엔티티에 UI는 사실 하나도 들어가지 않았습니다. 사실상 개인적인 생각으로는 feature에서 따로 UI로 만들어도 생각없지 않나 라는 판단하였습니다. 그게 맞는지는 잘 모르겠지만 그런 생각이 들었습니다."
FSD의 경우 계층, 슬라이스, 세그먼트라는 3가지의 관점을 조합해서 코드를 바라보자는 관점으로 이 관점으로 바라보니 엔티티 + UI라는 조합을 생각해보게 되는 것인데 꼭 그렇게 해야된다는 것은 없어요. 개발을 하다보면 계속 스스로의 판단을 하게 되는데 우선 직감을 느꼈다면 그 직감을 믿어보되 왜 그렇게 생각하게 되었는가에 대해서는 언어로 논리적으로 설명할 수 있을 만큼 충분히 파면서 근거를 만들어보는 시도를 해보기를 바래요.
Q) 의존성 방향만 유지된다면 shared -> entities -> widgets -> features -> pages로 가도 될까요? FSD 원칙에 위반돼서 안되는 것일지 궁금합니다. 예를 들면 widgets에서 pagination을 구현해서 features의 ui에서 갖다 쓰는거죠.
=> 본인의 생각이 그러하다면 그렇게 만들어도 무방합니다. 그런데 팀 프로젝트라면 그래서 우리는 FSD를 쓰겠다고 하면 사실상의 표준과 규약이 있기 때문에 그 약속을 합의하지 않으면 혼란이 가중될거에요. 나만 그렇게 생각한들 다른 사람들도 그렇게 생각하지 않으면 규칙이 되지 못하니까요. 일반적으로 널리 알려진 방법을 사용할때에는 남들도 대개 비슷하게 생각하는 컨벤션을 최대한 따라 진행하면서 함께 하는 사람과의 합의를 이끌어 낼 수 있다면 전혀 문제없다고 생각합니다.
Q) 실무나 아니면 간혹 구글링으로 서칭을 해보면 간혹 의존성에 대한 역전하는 허용하는 사례들을 본 것 같은데, 이런 케이스의 경우 어떤 룰을 세워서 허용하는 게 좋을까요?
=> 의존성을 역전이란 가령 옵저버 패턴의 경우 클릭 이벤트 처리는 원래 컴포넌트 내부에서 처리하는 로직이지만 컴포넌트에서 클릭 동작을 외부에 위임하면서 만들면서 컴포넌트가 클릭 동작을 가지고 있는게 아니라 컴포넌트를 가지고 있는 앱에서 클릭동작을 가질 수 있도록 하고 이를 주입하는 방식을 말합니다. Array.method나 TanstackQuery등도 마찬가지 이구요.
=> OCP 원칙에 따라서 확장을 하는 것 상위로 위임하고 반복되는 구현의 세부사항은 하위로 숨기면서 의존성을 관리하는 방법을 항상 생각하면 좋겠습니다.
Q) 큰 사이즈의 프로젝트에서 FSD를 사용한 케이스가 있을까요? 어떤 폴더 구조를 가지고 있는지 궁금합니다.
=> 케이스에 대한 예시들은 인터넷에서도 찾아볼 수 있으나 회사의 코드들을 직접 보기는 힘든 것 같습니다. 일부 FSD를 도입했다 나아졌다는 사례등은 접할 수 있지만 대부분의 말미에는 FSD를 그대로 적용하지는 않았다는 식의 얘기들이 많은걸로 보아서 적절히 개념을 혼합해서 사용하는 형태가 되지 않을까 생각합니다. 에전에 아토믹 디자인 패턴이 그랬던것 처럼요.
FSD를 그대로 쓰려고 하기보다는 현대적인 components, services, utils, hooks 등을 쓰더라도 코드를 계층적으로 모듈적으로 바라볼수 있는 계기가 되었기를 바래요. 나머지는 실무를 하면서 좋은 구조를 발견해나가시길 바래요.
화이팅입니다!