Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2단계 - 장바구니] 호프(김문희) 미션 제출합니다. #107

Merged
merged 91 commits into from May 27, 2022

Conversation

moonheekim0118
Copy link

@moonheekim0118 moonheekim0118 commented May 20, 2022

안녕하세요 ✨ 발리스타님 ✨ 호프입니다! 일주일만에 뵙습니다 :) 저번에 좋은 리뷰 덕분에 스텝2에서도 (나름..?) 저만의 방향성을 잡고 구현할 수 있었어요 :) 감사드립니다!

msw 로 서버 모킹을 했기 때문에 로컬에서만 실행 됩니다 😭 ...

✨ Step2 구현 사항

  • 단위 테스트 작성 ( react-testing-library)
    • Reducer 테스트 작성
    • useReduxState 커스텀 훅 테스트 작성
  • msw 를 활용해 API mocking
  • 장바구니 페이지 작성
    • 아이템 삭제 기능 구현
    • 수량 변경 기능 구현
    • 선택 상품 삭제 기능 구현

✨ Step1 에서부터 추가된 Redux 적용 사항

  • 장바구니 아이템을 리덕스 스토어에 저장하도록 구현했습니다.
  • 장바구니 수량 업데이트 할 경우, 스토어에 저장된 상태를 업데이트 해주었습니다.
  • 장바구니 아이템을 삭제/추가 할 경우 스토어에 저장된 상태를 업데이트 해주었습니다.

✨ 커스텀 훅

리듀서 별로 커스텀훅을 분리하지 않고, 비즈니스 로직 단위로 커스텀훅을 분리해서, 사용하는 곳에서 불러오도록 구현해보았습니다..! 그리고 커스텀훅은 무조건 페이지컴포넌트에서만 사용하도록 하였고, 컴포넌트는 props 만 받도록 했어요! (컴포넌트 재사용성을 높이기 위해서 이렇게 구현했습니다. 저번에 주신 조언도 전역 상태관리를 이해하는데 굉장히 도움이 되었어요ㅎㅎ)

그런데 이렇게 사용하는게 맞는지 확신은 안들어서, 구조에 대해서 조언해주시면 감사하겠습니다 : D

- useReduxtState ( key 값에 따라 dispatch 와 state를 가져오는 훅)
- useCart (장바구니 아이템을 불러오는 훅  )
- useAddCartItem ( 장바구니에 아이템을 추가하는 훅 ) 
- useDeleteCartItem (장바구니에 아이템을 삭제하는 훅)
- useProduct (개별 상품을 불러오는 훅)
- useProducts (상품 리스트를 불러오는 훅)
- useUpdateCartItem (장바구니 아이템을 수정하는 훅)

✨ 비동기 처리 상태 수정

이전

  • isLoding, isError 로만 관리했습니다.
  • 그런데 이렇게 관리하니..! 분기 처리하기가 굉장히 까다로워지더라구요! 그래서 아래와 같이 수정했습니다.

현재

  • isLoading, IsSucceed, IsError

✨ 단위테스트 작성 기준

개인적으로..! 컴포넌트 렌더링 테스트는 이미 스토리북 테스트를 작성을 해놓았기 때문에 무의미하다고 판단했습니다. 또한 단위 테스트이기 때문에 비즈니스 로직(기능) 을 중심으로 테스트하는게 맞다고 생각하여, 리듀서 함수useReduxState 커스텀 훅 두 가지에 대한 단위 테스트를 작성하였습니다.

💙 폴더 구조
📦src
 ┣ 📂__tests__
 ┃ ┣ 📜cartReducer.test.js
 ┃ ┣ 📜productReducer.test.js
 ┃ ┣ 📜productsReducer.test.js
 ┃ ┗ 📜useReduxState.test.js
 ┣ 📂assets
 ┃ ┣ 📂fonts
 ┃ ┃ ┣ 📜DoHyeon-Regular.ttf
 ┃ ┃ ┗ 📜YeonSung-Regular.ttf
 ┃ ┣ 📂mock
 ┃ ┃ ┗ 📜index.js
 ┃ ┣ 📂png
 ┃ ┃ ┣ 📜emptyImg.png
 ┃ ┃ ┣ 📜errorApiImg.png
 ┃ ┃ ┣ 📜noImage.png
 ┃ ┃ ┗ 📜notFoundImg.png
 ┃ ┗ 📂svg
 ┃ ┃ ┣ 📜bigCart.svg
 ┃ ┃ ┣ 📜smallCart.svg
 ┃ ┃ ┣ 📜smallTrashbin.svg
 ┃ ┃ ┗ 📜spinner.svg
 ┣ 📂components
 ┃ ┣ 📂Button
 ┃ ┃ ┣ 📜Button.jsx
 ┃ ┃ ┣ 📜Button.stories.js
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂CartContainer
 ┃ ┃ ┣ 📜CartContainer.jsx
 ┃ ┃ ┣ 📜CartContainer.stories.js
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂CartControlBar
 ┃ ┃ ┣ 📜CartControlBar.jsx
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂CartItem
 ┃ ┃ ┣ 📜CartItem.jsx
 ┃ ┃ ┣ 📜CartItem.stories.js
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂CheckBox
 ┃ ┃ ┣ 📜CheckBox.jsx
 ┃ ┃ ┣ 📜CheckBox.stories.js
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂Header
 ┃ ┃ ┣ 📜Header.jsx
 ┃ ┃ ┣ 📜Header.stories.js
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂ImgWrapper
 ┃ ┃ ┣ 📜ImgWrapper.jsx
 ┃ ┃ ┣ 📜ImgWrapper.stories.js
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂Layout
 ┃ ┃ ┗ 📜Layout.jsx
 ┃ ┣ 📂MenuItem
 ┃ ┃ ┣ 📜MenuItem.jsx
 ┃ ┃ ┣ 📜MenuItem.stories.js
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂PaymentBox
 ┃ ┃ ┣ 📜PaymentBox.jsx
 ┃ ┃ ┣ 📜PaymentBox.stories.js
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂ProductContainer
 ┃ ┃ ┣ 📜ProductContainer.jsx
 ┃ ┃ ┣ 📜ProductContainer.stories.js
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂ProductDetail
 ┃ ┃ ┣ 📜ProductDetail.jsx
 ┃ ┃ ┣ 📜ProductDetail.stories.js
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂ProductItem
 ┃ ┃ ┣ 📜ProductItem.jsx
 ┃ ┃ ┣ 📜ProductItem.stories.js
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂Skeleton
 ┃ ┃ ┣ 📜Skeleton.jsx
 ┃ ┃ ┣ 📜Skeleton.stories.js
 ┃ ┃ ┗ 📜style.js
 ┃ ┗ 📂Title
 ┃ ┃ ┣ 📜Title.jsx
 ┃ ┃ ┣ 📜Title.stories.js
 ┃ ┃ ┗ 📜style.js
 ┣ 📂constants
 ┃ ┗ 📜index.js
 ┣ 📂hooks
 ┃ ┣ 📜useAddCartItem.js
 ┃ ┣ 📜useCart.js
 ┃ ┣ 📜useDeleteCartItem.js
 ┃ ┣ 📜useProduct.js
 ┃ ┣ 📜useProducts.js
 ┃ ┣ 📜useReduxState.js
 ┃ ┗ 📜useUpdateCartItem.js
 ┣ 📂mocks
 ┃ ┣ 📜browser.js
 ┃ ┗ 📜handlers.js
 ┣ 📂pages
 ┃ ┣ 📂Cart
 ┃ ┃ ┣ 📜index.jsx
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂NotFound
 ┃ ┃ ┗ 📜index.jsx
 ┃ ┣ 📂Product
 ┃ ┃ ┣ 📜index.jsx
 ┃ ┃ ┗ 📜style.js
 ┃ ┣ 📂ProductList
 ┃ ┃ ┗ 📜index.jsx
 ┃ ┗ 📜index.js
 ┣ 📂reducers
 ┃ ┣ 📂cart
 ┃ ┃ ┣ 📜cart.actions.js
 ┃ ┃ ┣ 📜cart.reducer.js
 ┃ ┃ ┗ 📜cart.thunk.js
 ┃ ┣ 📂product
 ┃ ┃ ┣ 📜product.actions.js
 ┃ ┃ ┣ 📜product.reducer.js
 ┃ ┃ ┗ 📜product.thunks.js
 ┃ ┣ 📂products
 ┃ ┃ ┣ 📜products.actions.js
 ┃ ┃ ┣ 📜products.reducer.js
 ┃ ┃ ┗ 📜products.thunks.js
 ┃ ┗ 📜rootReducer.js
 ┣ 📂store
 ┃ ┗ 📜configureStore.js
 ┣ 📂style
 ┃ ┣ 📜globalStyle.js
 ┃ ┗ 📜theme.js
 ┣ 📂utils
 ┃ ┣ 📜apiClient.js
 ┃ ┗ 📜parsePrice.js
 ┣ 📜App.js
 ┣ 📜Routes.js
 ┗ 📜index.js

👀 고민사항

MSW 핸들러에 로직을 추가하는게 맞을지

  • 이번에 서버 모킹을 msw를 사용했는데, msw 에 제가 직접 자바스크립트로 장바구니 추가/삭제/수정 등의 기능들을 추가했습니다. 그런데, msw는 단순히 서버 모킹이기 때문에 굳이 이렇게 직접 로직을 작성해줘야하는지 고민이 됩니다. 로직 처리 없이 \ mock 데이터만 보내줘도 될까요?

성능 최적화 관련

  • 아직까지 앱 규모가 작아서 그런지 useCallback 이나 React.memo 등의 성능 최적화 훅을 사용해야겠다!! 라고 와닿지 못했습니다 😭 😭 아직 메모이제이션 최적화를 언제 써야겠다!라는 기준이 없어서 많이 모호해요! 혹시 발리스타님은 어떤 기준으로,어느 상황에 useCallback 이나 React.memo 를 사용 하시나요 👀 ?

- products list get mocking api 작성
- 개별 product get mocking api 작성
- 스토어에 여러 isLoading, isError 상태가 추가될 경우를 대비하여 범용성 있게 수정
- succeed 상태 추가
- CartControlBar를 CartContainer 로부터 분리
- 기존에 페이지에서 props 로 내려주던 방식에서 컴포넌트 내부에서 핸들링 하도록 수정
- Promise.all 사용하여 구현
- 기존에 객체로 export default -> 변수로 export 하도록 수정
- 도메인(페이지단위) 별로 분리
@moonheekim0118
Copy link
Author

안녕하세요 발리스타님 :D 다시 한번 리뷰 요청 드리는 호프입니다!
지난 번에 전역상태에 대한 좋은 조언과 리뷰 감사드립니다! 덕분에 생각지도 못했던 부분들을 정말 많이 고민 해 볼 수 있었고, 제 고민을 코드에 많이 녹여내려는 시도를 해보았어요. 그 과정에서 코드는 아직 완벽하지 않지만 많이 성장함을 느끼는 요즘입니다!

코드가 많이 변경되어서, 먼저 방대한 양의 PR 메시지와 file changes에 양해를 구합니닷..죄송합니다.. 😭 ..
변경 사항을 아래에 정리해보았는데요, 혹시 이해되지 않으시는 점이 있다면 언제든지 말씀주시면 감사하겠습니다 :DD

✅ 전역상태 대상 수정 및 useFetch 훅 작성

🧷 관련 커밋 링크

저번에 모든 API 에 대한 성공/실패 응답을 전역상태로 관리하는 것은 전역 의존이다.라고 조언주신 것을 계기 삼아서 전역 상태로 관리 할 상태들에 대한 기준을 마련하게 되었습니다.
저의 기준은,

  1. 데이터가 여러 Page 에서 참조될 가능성이 있다면
  2. API 요청의 비용이 너무 커서 캐싱이 필요하다면

전역 상태로 관리하자. 였습니다.

다시 말해서,

  • 데이터가 딱 하나의 Page 에서만 참조된다면,
  • API 요청 비용이 크지 않아서 캐싱이 필요하지 않은 수준이라면

굳이 전역 상태로 관리할 필요가 없이, 해당 페이지에서 Fetch 를 받아와서 상태로 저장해주면 되겠다고 생각했습니다.

또한 말씀주신대로, 모든 API 요청에 대한 isLoading, isError 상태를 어떻게든 컴포넌트가 알아야 할 상황이 오긴 할 텐데, (예를 들어 수량 변경 버튼을 눌렀을 때, 변경 버튼을 disabled 나 로딩상태로 처리해준다던지!) 그 때 마다 일일이 전역상태에 API 요청별 상태를 추가해주는 것도 전역의존 이라고 말씀하신 것을 깊이 느꼈어요.

따라서, API 요청마다 전역 상태와 분리되는, isLoading, isError 상태를 따로 가지고 있어야 한다고 생각했고 이를 처리해주는 useFetch 라는 함수를 작성하여, 전역 상태로 관리되지 않을 API 요청들을 페이지 단위에서 처리해주었습니다.

따라서, 현재 전역 상태로 관리하고 있는 것과 아닌 것을 정리하자면

🧷 이전

전역상태로 관리되는 것

  • Product(개별상품)
    • 개별상품 GET 요청
  • ProductList (전체상품)
    • 전체상품 GET 요청
  • Cart(장바구니)
    • 장바구니 GET 요청
    • 장바구니 ADD 요청
    • 장바구니 UPDATE 요청
    • 장바구니 DELTE 요청

🧷 현재

전역상태로 관리되는 것

  • Cart (장바구니)

    • 장바구니 GET 요청
    • 장바구니 SET 요청 ( 장바구니 업데이트 / 삭제 이후, 스토어 상태를 변경시켜주기 위함)
  • 장바구니의 경우 현재 구현되지는 않았지만, 앱의 여러 페이지에서 참조될 수 있다고 생각하여 전역상태로 유지했습니다.

useFetch 훅에서 handler 라는 인자를 받아서 data 가 업데이트 될 때마다 호출되는데요, 이는 Redux Store에 API 요청에 따른 새로운 데이터를 업데이트 시켜주기 위함이었습니다.
예를들어, 장바구니 삭제 요청을 useFetch 로 호출 한 후, handler (리덕스에 dispatch) 를 실행하여 Redux Store 에 저장된 장바구니 data 를 최신의 상태로 업데이트 해주도록 구현했습니다.

  • 물론 장바구니 수정 / 삭제 / 추가 와 같은 로직들은 아직 간단하고, 어차피 api 요청 후 리덕스를 거쳐야 해서, 이 정도 규모라면 리덕스에 의존해도 무방하다고 생각했지만! 연습삼아 한번 useFetch 로 분리해보았습니다ㅎㅎ


✅ 비즈니스 로직 훅 & 페이지 단위 훅 분리

🧷 관련 커밋 링크


  • 저번에 조언 주신대로, 공통으로 사용되는 비즈니스 훅 (useCart, useFetch) 을 작성하고, 해당 비즈니스 훅을 사용하는 페이지 훅 (useCartPage, useProductPage, useProductsPage) 을 작성해보았습니다.
  • 그리고 훅을 너무 잘게 자르지 않고, 하나의 훅에서 여러 함수 및 상태들을 반환 해주도록 구현해보았습니다.
    • 이렇게 하다보니 든 생각은, 처음부터 훅을 너무 잘게 나누지 말고, 도메인 단위 혹은 페이지 단위로 뭉쳐놓았다가 추후에 분리가 필요하다고 느껴질때 나누는게 맞다 입니다.
  • 페이지 단위로 훅을 나누니 사실 로직이 한번에 보여서, 가독성이 좋다고 생각이 되었어요.
  • 하지만 아직, 컴포넌트 단위 훅은 작성하지 않았습니다..! 비즈니스 로직이 담긴 컴포넌트의 로직까지 훅으로 분리 할 필요성을 아직 못느꼈기 때문입니다.


✅ 단위 테스트

🧷 관련 커밋 링크


저번에 답변 주셨던 대로, 대다수의 로직이 커스텀 훅(페이지 훅)에 있기 때문에, 컴포넌트 렌더 테스트는 진행하지 않았습니다. 그런데..! CartItem 이나 ProductItem 과 같은 컴포넌트는 비즈니스 로직을 가지고 있어서 테스트 대상이라고 판단이 되긴 했어요. 하지만 이에 대한 로직 테스트를 수행하려면, 해당 컴포넌트 내부의 로직을 훅으로 또 분리해주어야 하는데, 오로지 테스트를 위해서 훅으로 분리하는 것은 올바르지 않은 방향같아서 진행하지는 않았습니다.

그리고, 리듀서 테스트의 경우 저도 사실상 유의미하다고 생각하지는 않지만…! 그래도 테스트를 유지했고, 테스트 설명을 더 자세하게 기재하였습니다 ㅎㅎ



✅ 그 외) 컴포넌트 폴더 구조 수정

페이지 단위로 폴더 구조를 나누어서 아래와 같이 수정했습니다.

  • Common
    • 앱 전반에서 사용되는 컴포넌트
  • Cart
    • 장바구니 페이지에서 사용되는 컴포넌트
  • Product
    • 개별 상품 페이지에서 사용되는 컴포넌트
    • 전체 상품 페이지에서 사용되는 컴포넌트


✅ 그 외) Styled Component 네이밍 수정

  • 이전에는 StyledComponent 네이밍에 도메인이 깊게 관여했는데요 ( ex) ProductName… ProductDeleteButton..) 최대한 스타일링은 도메인을 반영하지 않아야한다고 판단했습니다.
    • 왜냐하면, 나중에 스타일링이나 레이아웃은 유지 된 채로, 해당 컴포넌트의 사용처가 달라질 수 있으니까요!
  • 그래서 최대한 네이밍에서 도메인을 제거하고자 했는데, 제대로 된지 모르겠습니다 ㅠ^ㅠ


그리고 메모이제이션의 경우 아직 메모이제이션이 필요하다!!라는 부분을 딱히 발견하지 못했고, 메모이제이션 훅에 큰 이점을 느끼지 못했기 때문에 아직 적용하지는 않았습니다 :)


정말 좋은 조언과 리뷰, 질문에 대한 답변 감사드립니다..!! 정말 많이 성장하는 한 주가 되었습니다 👍 👍 👍

Copy link
Contributor

@pocojang pocojang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요
발리스타님을 대신해서 왔습니다

현장에서 1 on 1 리뷰를 했으니 일부 피드백은 생략하겠습니다

순서의 중요성 생각하기

컴포넌트 내부의 코드조차 의존성이고 순서조차 규칙이 있다면 코드를 파악하고 유지보수하기에도 좋습니다.
Hooks로 추상화를 계속하고 계시는 것 같은데 지켜지지 않은 순서 그대로 추상화까지 이어지고 있습니다.

eslint-import-sort규칙처럼 스스로 규칙을 만들고 지켜보세요!

컴포넌트 구성

aa.jsx & aa.stories.js & style.js
로 매우 일관성을 잘 지키고 있으나..
style.js 네이밍이 계속 일관적이고 중복되다보니 코드를 읽을 때 헷갈리긴 하네요ㅠㅠ
(개인적인 의견)

Common 계층

어떤 이유로 만드셨는지 잘 모르겠는데...음
일단은 그 합당한 사유는 잘모르겠네요ㅠㅠ

컴포넌트 네이밍 규칙

  • container vs wrapper 헷갈리네요ㅠㅠ

커스텀 훅 분리

굉장히 잘 활용하고 계셔서 좋아요
다만 코멘트 리뷰에 남긴 것처럼 특정 컴포넌트에 의존성을 가지고 있는 경우 해당 컴포넌트의 바로 곁에 위치해주는게 어떨까요?

디렉터리 위치조차 의존성의 일부니까요


고생하셨습니다!!

@@ -3,6 +3,7 @@ module.exports = {
browser: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 configure 같은 경우 .js로 통일하시는걸까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 js 로 통일하기로 한 이유는, configure 파일이 여러개 있을 경우 js 확장자가 우선순위가 제일 높기 때문입니다 :)

Comment on lines 65 to 67
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.29.4",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

겹치는 eslint에 대해 확인해보세요!

Comment on lines -5 to +6
import Layout from 'components/Layout/Layout';
import ImgWrapper from 'components/ImgWrapper/ImgWrapper';
import Layout from 'components/Common/Layout/Layout';
import ImgWrapper from 'components/Common/ImgWrapper/ImgWrapper';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀

return (
<>
<Styled.Title>
댕냥 배송상품 ({React.Children.count(children)})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WoW..!!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

children (아마도 CartItem 컴포넌트) 개수에 따라서, 배송상품 개수가 렌더링 되도록 구현하면서 React.Children.count 를 사용할 수 있었어요
그런데 다시 생각해보면! html 구조에 따라서 쉽게 변경될 수 있는 사항이라서 props로 개수를 직접 내려주는게 더 안전할 것 같다고 생각하긴 합니다.

Comment on lines +13 to +16
<CheckBox checkedStatus={isChecked} onCheck={onControlToggleCheck} />
<span>전체 선택 / 해제</span>
</Styled.LeftBox>
<Styled.Button onClick={onControlClickButton}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onControl-이라는 네이밍 규칙이 혼란스럽네요ㅠㅠ

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

일단..해당 컴포넌트가 CartControlBar 이기 때문에 컴포넌트 관점에서
'ToggleCheck 를 Control 한다혹은Click Burtton을 Control 한다` 라는 의미를 살려주고 싶었어요.
그런데..그러다보니 동사 두개가 겹치니 매우 헷갈려졌네요 😢
이 부분 더 좋은 네이밍 고민해볼게요! 감사합니다 👍

import { METHOD } from 'constants';
import useFetch from 'hooks/useFetch';

const useCart = () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

심플하게 명확한 역할을 하는 Hooks로 좋네요 💯

display: flex;
justify-content: center;
align-items: center;
color: #fff;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

떠도는 컬러를 제거합시다!!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제거 완료하였습니다. 😎

Comment on lines +8 to +11
const handleChange = () => {
setChecked((checked) => !checked);
onCheck();
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useEffect()가 더 어울리지 않을까요?

@@ -1,5 +1,6 @@
import PropTypes from 'prop-types';
import Styled, { buttonSize, buttonColor } from './style';
import { buttonColor, buttonSize } from './style';
import * as Styled from './style';

const Button = ({ colorType, sizeType, children, ...rest }) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rest 말고 props 어떨까요?
어떻게 쓰이느냐에 초점을 맞춘 네이밍을 생각해보는거죠

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동의합니다..! 단순히 rest 는 '남은 props'라는 의미밖에 없네요! 어떻게 쓰이는지가 배제되어 있는 불친절한 네이밍이었네요!
rest 가 스타일드 컴포넌트에 props로 넘겨짐에도 불구하구요! 그래서 rest->props로 네이밍 수정해주었습니다.

775c54e

Comment on lines 3 to 4
PRODUCT: '/product',
CART: '/cart',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useRoutes 어때요?!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 마침 한번 적용해보고 싶었어서..! useRoutes 로 수정해보았습니다
확실히 라우팅을 객체로 관리할 수 있어서 편리하네요 👍
4a051b7

@pocojang pocojang merged commit c5fd138 into woowacourse:moonheekim0118 May 27, 2022
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.

None yet

3 participants