과제링크
https://adds9810.github.io/front_6th_chapter2-2/index.basic.html https://adds9810.github.io/front_6th_chapter2-2/index.advanced.html
과제의 핵심취지
- React의 hook 이해하기
- 함수형 프로그래밍에 대한 이해
- 액션과 순수함수의 분리
과제에서 꼭 알아가길 바라는 점
- 엔티티를 다루는 상태와 그렇지 않은 상태 - cart, isCartFull vs isShowPopup
- 엔티티를 다루는 컴포넌트와 훅 - CartItemView, useCart(), useProduct()
- 엔티티를 다루지 않는 컴포넌트와 훅 - Button, useRoute, useEvent 등
- 엔티티를 다루는 함수와 그렇지 않은 함수 - calculateCartTotal(cart) vs capaitalize(str)
기본과제
- Component에서 비즈니스 로직을 분리하기
- 비즈니스 로직에서 특정 엔티티만 다루는 계산을 분리하기
- 뷰데이터와 엔티티데이터의 분리에 대한 이해
- entities -> features -> UI 계층에 대한 이해
- Component에서 사용되는 Data가 아닌 로직들은 hook으로 옮겨졌나요?
- 주어진 hook의 책임에 맞도록 코드가 분리가 되었나요?
- 계산함수는 순수함수로 작성이 되었나요?
- Component에서 사용되는 Data가 아닌 로직들은 hook으로 옮겨졌나요?
- 주어진 hook의 책임에 맞도록 코드가 분리가 되었나요?
- 계산함수는 순수함수로 작성이 되었나요?
- 특정 Entitiy만 다루는 함수는 분리되어 있나요?
- 특정 Entitiy만 다루는 Component와 UI를 다루는 Component는 분리되어 있나요?
- 데이터 흐름에 맞는 계층구조를 이루고 의존성이 맞게 작성이 되었나요?
심화과제
- 이번 심화과제는 Context나 Jotai를 사용해서 Props drilling을 없애는 것입니다.
- 어떤 props는 남겨야 하는지, 어떤 props는 제거해야 하는지에 대한 기준을 세워보세요.
- Context나 Jotai를 사용하여 상태를 관리하는 방법을 익히고, 이를 통해 컴포넌트 간의 데이터 전달을 효율적으로 처리할 수 있습니다.
- Context나 Jotai를 사용해서 전역상태관리를 구축했나요?
- 전역상태관리를 통해 domain custom hook을 적절하게 리팩토링 했나요?
- 도메인 컴포넌트에 도메인 props는 남기고 props drilling을 유발하는 불필요한 props는 잘 제거했나요?
- 전체적으로 분리와 재조립이 더 수월해진 결합도가 낮아진 코드가 되었나요?
과제 셀프회고
항해의 절반을 지나오면서 과제를 해나가는 것 자체에는 익숙해졌지만, 매 과제마다 등장하는 새로운 개념과 이론에 여전히 허우적거리는 중입니다. 이번 과제에서 가장 큰 고민거리였던 것은 Entity와 UI의 개념과 역할 분리였습니다. 화요일에 진행되었던 팀원들과의 토론을 통해 다양한 관점을 접할 수 있었고, 이는 큰 도움이 되었습니다. "엔티티는 비즈니스 주체다", "앱의 명사에 해당하는 데이터 덩어리다"와 같은 명확한 정의부터, "UI는 어디까지 상태를 가져야 하는가?", "엔티티가 절대 해서는 안 되는 것은 무엇인가?"와 같은 실용적인 부분도 나눌 수 있었습니다. 막히는 것에 대한 질문에 답해주고 함께 고민해주는 팀원들 덕분에, 혼자였다면 한참을 헤맸을 길을 더듬더듬 나아갈 수 있었습니다. 그 덕분에 어찌어찌 과제를 완성할 수 있었습니다. 솔직히 말하면 "깊은 이해"라고 하기에는 아직 부족하지만, 단순히 코드를 작성하는 것을 넘어서 **"왜 이렇게 분리해야 하는지"**에 대해 생각해보게 되었고, 앞으로 비슷한 상황에서 "이렇게 분리하는 게 맞나?"라는 질문을 던질 수 있게 되었다는 점이 가장 큰 성장이었습니다.
과제를 하면서 내가 알게된 점, 좋았던 점은 무엇인가요?
- Props Drilling의 구체적 해결: 이론적으로만 알고 있던 Props Drilling 문제를 기본과제에서 컴포넌트를 분리하는 과정에서 실제로 불편함을 겪고, 심화과정에서 Jotai로 해결해보면서 깊이 있게 이해할 수 있었습니다. 특히 Basic에서
App.tsx에서isAdmin,cart,totalItemCount등 많은 props를Header와CartPage로 전달하는 과정에서 "이게 맞나?" 하는 의문을 가졌고, Advanced에서는 Jotai를 도입하여 각 컴포넌트에서 직접isAdminAtom,cartAtom등을 사용할 수 있게 되어 코드가 훨씬 깔끔해진 것을 체감했습니다. 이론으로만 알던 "props drilling이 문제다"라는 말이 실제로 어떤 의미인지 몸소 경험할 수 있었던 점이 좋았습니다. - 컴포넌트 독립성과 재사용성:
ProductForm과CouponForm에서 자체 상태(productForm,couponForm)를 관리하고, Jotai Actions를 직접 호출하여 비즈니스 로직을 중앙화하는 패턴을 학습했습니다. 다만 여전히 일부 props(showProductForm,setShowProductForm등)는 받고 있어 완전한 독립성은 달성하지 못했습니다. - 상태 관리 복잡성의 이해: React 애플리케이션에서 상태 관리가 어떻게 복잡해지는지, 그리고 이를 해결하는 다양한 방법들을 체감할 수 있었습니다.
이번 과제에서 내가 제일 신경 쓴 부분은 무엇인가요?
- 단계적 접근: 이전 과제에서 한 번에 모든 것을 바꾸려다가 테스트가 실패하는 경험을 통해, ai를 활용하던 그렇지 않던 버튼 등 ui 컴포넌트 - models - utils - 엔티티 컴포넌트 - Jotai기반 상태관리(심화) 점진적으로 하나씩 변경하고 각 단계마다 테스트를 통과시키는 방식으로 접근했습니다.
- 점진적 개선과 분리 기준에 대한 고민: 단순히 코드를 분리하는 것을 넘어서, 각 단계에서 "어떻게 분리할 것인가"를 깊이 고민했습니다. UI 컴포넌트 → models → utils → 엔티티 컴포넌트 → Jotai 기반 상태관리(심화) 순서로 점진적으로 개선하면서, 각 단계마다 "이 로직은 어디에 속해야 할까?", "이 함수는 순수 함수인가 훅인가?", "이 컴포넌트는 UI인가 엔티티인가?"라는 질문을 계속 던졌습니다. 특히 AI의 제안이 '순수 함수'와 '훅' 사이에서 오락가락할 때마다 혼란스러웠지만, 결국에는 각 요소의 책임과 역할을 명확히 정의하는 것이 중요하다는 것을 깨달았습니다.
- Props의 최소화와 상태 관리의 중앙화: 어떤 상태가 전역적으로 관리되어야 하는지, 어떤 상태는 컴포넌트 내부에 남아있어도 되는지(예: 폼 입력값) 신중하게 판단했습니다. Jotai의 atom을 설계하면서, 이 상태가 애플리케이션의 다른 부분과 어떻게 상호작용할지 고민하며 최대한 props를 넘기지 않고도 컴포넌트가 독립적으로 작동할 수 있도록 구조를 잡고자 많이 노력했습니다.
이번 과제를 통해 앞으로 해보고 싶은게 있다면 알려주세요!
- '엔티티' 개념 정복하기: '기능을 가진 대상'이라는 저만의 정의를 넘어, '엔티티'가 무엇인지 명확하게 설명할 수 있을 때까지 학습하고, 다음 프로젝트에서는 자신감을 가지고 엔티티 기반으로 컴포넌트와 로직을 설계하고 싶습니다.
- Jotai 제대로 배워서 적용해보기: 기한에 급급해 심화 과제에서 AI에 의존해 겨우겨우 에러를 해결했던 경험을 반복하고 싶지 않습니다. Jotai가 어떻게 상태를 관리하는지 공식 문서를 보며 직접 코드를 짜보고, 그 원리를 이해하여 능숙하게 사용하고 싶습니다.
리뷰 받고 싶은 내용이나 궁금한 것에 대한 질문 편하게 남겨주세요 :)
- Jotai
atom설계 : advanced/store/atoms.ts에서 atom들을 작성했는데, 혹시 더 효율적으로 atom을 구성하거나 조합할 수 있는 방법이 있을까요? 예를 들어, 액션 atom들을 하나의 파일로 관리하는 것이 좋은 패턴인지, 아니면 관련된 atom과 함께 두는 것이 나을지 궁금합니다.
과제 피드백
지혜님 안녕하세요! 전반적으로 잘 정리해주셨습니다 ㅎㅎ 리팩토링의 핵심처럼 기능이 올바르게 동작하는 것, 테스트를 기반해서 점진적으로 코드를 개선하고 접근하는 방식으로 하셨다니 좋은 경험이셨을것 같아요. 코드는 전반적으로 잘 정리해주셨는데요! 다만, 지혜님이 의견을 남겨주신 것처럼 atom에 대한 부분에 대한 답변 드려보면 일단 제 기준에서는 엄~청 복잡하지는 않은 것 같아서 하나로 관리해도 전혀 무리는 없을 것 같아요. 왜 한군데서 처리를 했는지 이해도 되구요. 다만, 기반이 되는 규칙을 하나 만들고 유연하게 적용하면 좋을것 같아요. 기반이 되는 규칙으로는 도메인 별로 분리하도록 하고 (그렇게 하면 도메인 로직을 찾기도 편하고 관련 기능끼리 모여서 응집도도 높아질거에요) 각 파일내에서 파생 상태를 만들어서 관리하거나, 합쳐서 관리하는 형태로 분리하면 좋지 않을까! 싶습니다.
고생하셨고 다음주 과제도 화이팅입니다!!