https://elli-lee.github.io/front_6th_chapter2-2/basic.html https://elli-lee.github.io/front_6th_chapter2-2/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는 잘 제거했나요?
-
전체적으로 분리와 재조립이 더 수월해진 결합도가 낮아진 코드가 되었나요?
과제 셀프회고
과제를 하면서 내가 알게된 점, 좋았던 점은 무엇인가요?
-
커스텀 훅을 통한 관심사 분리 useCart, useProducts, useCoupon 등 엔티티마다 훅을 분리하여 각각의 책임을 구분하고자 했습니다. 각 훅이 하나의 엔티티만 다루도록 전체 소스에서 해당 엔티티에 대한 부분들만을 최대한 훅으로 옮겼습니다.
-
Jotai를 활용한 전역 상태 관리 우선 atomWithStorage를 통해 자동 localStorage 동기화를 할 수 있다는 부분이 신기하고 편리했습니다. basic 과제에서 한가득 넘겨주던 props들을 jotai를 사용하니 컴포넌트별로 필요한 상태만 구독할 수 있게 되어 명확한 책임 분리가 된 것 같습니다. 또 Props drilling이 제거되어 컴포넌트 간 결합도가 줄어들고 가독성이 훨씬 향상되는 걸 경험할 수 있어서 좋았습니다.
-
UI 로직과 비즈니스 로직 분리 커스텀 훅을 사용해 UI 로직과 비즈니스 로직을 최대한 분리하고자 했습니다. 어떤게 UI 로직이고, 어떤게 비지니스 로직인지 곰곰이 생각해보면서 두개의 차이에 대해 조금씩 더 감이 오게 되었습니다.
이번 과제에서 내가 제일 신경 쓴 부분은 무엇인가요?
- 순수 함수 분리 refactoring(hint)를 참고해서 models/cart.ts에 비지니스 로직이 포함된 함수에서 어떻게 일부를 순수함수로 분리할 것인지 고민했습니다. 순수함수를 작성할 때
- UI와 관련된 로직 없음
- 외부 상태에 의존하지 않음
- 모든 필요한 데이터는 파라미터로 전달받음 이 세가지를 지키기 위해 고민했습니다.
- 커스텀 훅 분리 basic 과제를 진행 할 때 엔티티별로 커스텀 훅 분리를 시작했는데, 특정 엔티티의 커스텀 훅에서 다른 엔티티와 관련된 로직을 사용해야 하는 경우가 있었습니다. 구체적인 예를 들면, notification 엔티티와 관련하여 addNotification, removeNotification을 useNotification으로 분리시켰더니, addNotification 때문에 useNotification이 useCart, useProduct 등등 대부분의 다른 훅에서 필요했습니다. 처음에는 useCart, useProduct 에서 useNotification을 호출하면 되지 않을까 했는데, 커스텀 훅이 호출 될 때마다 새로운 인스턴스를 생성해서 상태가 공유되지 않는 이슈가 있었습니다. 결국 addNotification을 각각의 커스텀 훅에 인자로 넘겨주는 방식으로 처리를 했습니다.
이번 과제를 통해 앞으로 해보고 싶은게 있다면 알려주세요!
basic 과제를 진행하면서 컴포넌트에 props를 한가득씩 넘겨줘야 하고 props drilling이 심해서 컴포넌트를 작은 단위로 분리하지 않고 최대한 크게크게 분리했는데, jotai를 사용한 심화과제에서 props drilling 문제가 해결되었으니 조금 더 컴포넌트도 분리해보고 싶습니다. 또, advanced 과제를 refactoring(hint)폴더에 맞게 리팩토링을 다시 해보고 싶습니다.
리뷰 받고 싶은 내용이나 궁금한 것에 대한 질문 편하게 남겨주세요 :)
([이번 과제에서 신경쓴 부분 > 2. 커스텀 훅 분리] 내용에 이어지는 질문입니다.) basic 과제에서 결국 addNotification을 각각의 커스텀 훅(useProduct, useCart 등등)을 호출할 때 인자로 넘겨주는 방식으로 처리를 했는데요, 이렇게 넘겨주면 어쨌든 useProduct, useCart 훅이 notification 관련 처리를 하고 있는 거니까 각 엔티티별로 적절한 분리를 하지 못한거라고 생각하는데 맞을까요? 적절한 분리가 되지 않은거라면 이 addNotification을 어떻게 처리해야 했는지 궁금합니다
과제 피드백
유진님 고생하셨습니다~ 회고를 읽어보니까 과제를 진행하시면서 단순히 개선만 하는게 아니라 어떤 기준으로 어떻게 코드를 분리해야 하는지 고민을 깊게 하신 것 같아서 좋네요! 전반적으로 과제는 잘 진행해주셨는데요. 질문주셨던 부분에서 notification에 대해 상태를 공유해야 하는 부분에 대해서 고민이 많으셨던 것 같은데요. 말씀해주신대로 이상적인 상황에 있어서는 사실 각 커스텀 훅에 인자로 넘겨주고 의존성을 갖게 하면 좋지 않은 관점은 있는것 같아요. 가장 아름답게 각각의 로직을 분리하고 합쳐서 사용하는 방식으로는 이벤트 드리븐 아키텍쳐를 쓰거나.. 고차 훅 패턴 같은것들을 써서 분리를 할 수는 있을 것 같은데요. 지금의 구조에서는 해당 동작이 단순하고 분리의 비용이 더 클 수 있어서, 그리고 전역 상태 라이브러리를 사용할 수 있으니 훅에서 주입을 받아 사용하기 보다는 해당 상태에 접근해서 개선을 하면 충분하지 않을까 싶네요!
고생하셨고 다음주도 화이팅입니다!~~