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단계 - 상품 목록] 초코(강다빈) 미션 제출합니다. #77

Merged
merged 46 commits into from
Jun 12, 2024

Conversation

00kang
Copy link
Member

@00kang 00kang commented Jun 10, 2024

안녕하세요 하루, 초코🍫입니다.
지난 미션 1단계에서 오류해결을 위한 힌트가 아주 도움이 많이 되었습니다.
포기하지 않고 끝까지 리뷰해주셔서 감사합니다 🙇‍♀️


💻 로컬 실행

npm run dev
npm run test

🔗 배포 링크

바로가기


🔑 키워드 및 학습 목표

  • 서버 상태 관리, React Query
  • React Query를 사용하여 서버 상태를 관리할 수 있다.
  • API 연동 과정에서 발생하는 다양한 에러 상황에 대응하고 사용자에게 피드백을 제공할 수 있다.

😮‍💨 상황공유

이번 미션은 react query를 사용하도록 리팩터링하는 것이었지만, step1 진행이 느렸던 관계로 아직 구현 중입니다!
처음 사용해 보는 것이라 더욱 속도가 안 나는 것 같은데요, 리팩터링 단계에서 같이 올릴 수 있도록 해보겠습니다

+) 추가로 페이지 확인할 때 chomre의 설정에서 안전하지 않은 콘텐츠를 허용으로 바꿔줘야 제대로 보인다고 합니다!


❓ 질문사항

  • 상품 목록에서도 장바구니 모달 내에서도 수량 조절이 가능한데요, 저는 0으로 내려가면 장바구니에서 제거되고 담기 버튼이 나타나도록 했습니다. 그런데 장바구니 모달 내에서는 별도로 삭제 버튼이 있기 때문에 수량조절은 최소 1까지만 가능하고, 삭제버튼을 클릭해야만 삭제 되어야 하는가 고민이 있습니다. 일단 제 생각에는 이 동작이 어색하지 않기 때문에 0까지 조절 가능하도록 했는데 하루의 생각은 어떤 것일까요??
  • 현재 코드 수준에서 필요 이상의 api 요청이 일어나고 있을까요? 지난 1단계에서 최대한 반영해보려고 했는데, 리팩터링이 잘 되었는지 궁금해요! api 요청 횟수를 신경쓰며 작업해본 적이 없다보니 어떤 타이밍에 이런 것들을 체크하면 될지 모르겠어요. 하루는 어떻게 작업하시나요?

@365kim
Copy link

365kim commented Jun 10, 2024

( 내일 이어서 리뷰 드릴게요! 내일 일정이 조금 빠듯해서 시간은 조금 늦어질 수 있을 것 같습니다 🙏 그 전에 브랜치 정리는 미리 진행해주셔도 좋을 것 같아요. )

00kang added 24 commits June 11, 2024 10:01
src/App.tsx Outdated
Comment on lines 8 to 12
<>
<Header />
<ToastNotification />
<ProductSection />
</CartProvider>
</>
Copy link

Choose a reason for hiding this comment

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

에러가 발생하면 context API를 활용하여 ToastNotification 컴포넌트를 띄우도록 했는데, 쿼리 각각의 isError나 onError를 활용하여 수정하려고 합니다! 그런데 App 을 감싸면서 한번에 처리할 수 있는 방법이 있을까요?

제가 질문을 잘 이해한 것이 맞다면, 다음의 내용을 참고해보시면 좋을 것 같습니다 :)

Copy link
Member Author

Choose a reason for hiding this comment

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

  queryCache: new QueryCache({
    onError: (error) => {
      showToast(error.message);
    },
  }),

context API를 활용한 에러 관리에서 query를 활용한 에러 관리로 변경했습니다! 이렇게 수정한 게 맞을까요??

Copy link

Choose a reason for hiding this comment

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

retry 3회 후(+ 이때는 Loading UI도 잘 표시되고) 에러 발생 시 토스트도 잘 표시되는 것으로 확인했습니당 👍

Screen.Recording.2024-06-12.at.9.54.10.PM.mov

Comment on lines 36 to 38
{!isError &&
!isLoading &&
cartItems &&
Copy link

Choose a reason for hiding this comment

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

&& 가 조금 많아 보여서 혹시 33 line 위치에 early return 처리하면 어떨까요?

// e.g.
if (isLoading) {
  return null
}
return 정상컴포넌트

Copy link

@365kim 365kim left a comment

Choose a reason for hiding this comment

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

초코, 안녕하세요 :)
2단계 작업 잘봤습니다.

리뷰가 늦어졌는데 기다려주셔 감사합니다 🙌 시간이 정말 타이트했는데 2단계 요구사항 구현 및 개선작업까지 적극적으로 진행해주신 것으로 확인했어요 💯 에러 핸들링, api 호출 최적화, UX 고려까지 다양한 방면으로 고민해주시는 모습도 너무 좋았습니다.

코드 보면서 생각나는 것들 코멘트 남겨보았는데 천천히 확인해보시고, 반영 완료되시면 리뷰 재요청 부탁드릴게요 :) 수고하셨습니당 🍫🍫🍫🍫🍫

@00kang
Copy link
Member Author

00kang commented Jun 12, 2024

안녕하세요 하루, 초코🍫입니다.
어느덧 레벨2의 마지막 리뷰요청일 것 같네요. 마지막까지 잘 부탁드립니다!
+) 시원섭섭하지만, 마지막 리뷰어가 하루여서 좋았답니다.(다정한 디엠도 감사합니다)


💻 로컬 실행

npm run dev
npm run test

🔗 배포 링크

바로가기


✅ 주요 변경 사항

  • CartActionButton을 AddToCartButton 으로 변경 : 14576f6
  • CartModalcontent 에서 CartItem 컴포넌트 분리하여 정리 : a4c3263
  • useProducts 훅 정리(api호출 메서드 분리, 무한스크롤은 useInfiniteQuery 사용) : 938e27c
  • 에러 관리 : d5fb743 c6eb906

return (
<BaseButton onClick={onClick}>
<BaseButton onClick={onClick} ariaLabel="상품 담기 버튼">
Copy link

Choose a reason for hiding this comment

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

👍

const src = type === COUNTER_BUTTON_TYPES.INCREMENT ? PlusIcon : MinusIcon;
const ariaLabel = type === COUNTER_BUTTON_TYPES.INCREMENT ? "증가 버튼" : "감소 버튼";
Copy link

Choose a reason for hiding this comment

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

버튼 요소일 경우, 버튼임을 알려주기 때문에 aria-label에는 '버튼' 텍스트를 제거해도 좋겠습니다 :)

Screenshot 2024-06-12 at 9 26 06 PM

const rootElement = document.getElementById("root");
const rootWidth = rootElement ? window.getComputedStyle(rootElement).width : "430px";
const rootWidth = window.getComputedStyle(rootElement!).width;
Copy link

@365kim 365kim Jun 12, 2024

Choose a reason for hiding this comment

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

반영 감사합니다 :) ( 제가 제안드리긴 했지만 non-null assertion은 정말로 단언할 수 있을 때만 유의해서 사용해야합니다! )

Copy link
Member Author

@00kang 00kang Jun 13, 2024

Choose a reason for hiding this comment

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

주의하면서 사용해야겠군요!

@@ -1,6 +1,6 @@
import { PlusShoppingCartIcon } from "../../assets";
import * as S from "./AddToCartButton.styled";
Copy link

@365kim 365kim Jun 12, 2024

Choose a reason for hiding this comment

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

역시 사소한데, 커밋 프리픽스의 style:은 세미콜론 등 코드 포맷팅을 의미합니다. (프론트엔드의 스타일 코드가 아닌)

style : styled.ts 파일을 * as S 로 임포트하도록 수정

이렇게 코드 컨벤션을 적용해주시는 작업의 경우 refactor: 로 작성해주셔도 좋을 것 같네용 :)

Copy link
Member Author

Choose a reason for hiding this comment

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

커밋 프리픽스가 너무 헷갈리네요,,ㅎ 주의하겠습니다

Comment on lines +17 to +20
page = 0,
size = 20,
sort = [],
category = "전체",
Copy link

Choose a reason for hiding this comment

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

기본값이 있다면 interface에서 각각을 optional로 정의해도 좋겠습니다 :)

또, TSDoc 문법에 따라 defaultValue를 명시해서, 함수를 사용하는 쪽에서 hover 만으로 힌트를 받도록 해도 좋겠습니당

interface getProductsProps {
  /** @defaultValue 0 */
  page?: number;
  /** @defaultValue 20 */
  size?: number;
  /** @defaultValue [] */
  sort?: string[];
  /** @defaultValue '전체' */
  category?: string;
}
Screenshot 2024-06-12 at 10 01 06 PM

useEffect(() => {
fetchProducts();
}, [setErrorStatus, page, sortOption, category]);
const { data, error, fetchNextPage, hasNextPage, isFetching, refetch } = useInfiniteQuery({
Copy link

Choose a reason for hiding this comment

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

👏👏👏👏👏

Comment on lines 10 to 11
const handleDelete = async (id: number) => {
removeItem(id);
const handleDelete = async (cartItemId: number) => {
removeItem({ cartItemId });
Copy link

Choose a reason for hiding this comment

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

오 더 명확한 네이밍 넘 좋은데용 👍

Copy link

@365kim 365kim left a comment

Choose a reason for hiding this comment

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

image

초코, 상품목록 미션 완료 축하드립니당 🎊

마지막까지 적극적으로 리뷰 반영해주시고 코드 개선해주셔서 감사합니다 💯💯💯 주요 변경내역까지 일목요연하게 정리해주신 덕분에 변경점 파악하기 수월했어요 👍

레벨2 수료 축하드리고, 또 방학동안 충전 시간 잘 보내시길 바라요 💙
레벨2 고생 많으셨습니당 👏👏👏👏👏

@365kim 365kim merged commit 7a9d22a into woowacourse:00kang Jun 12, 2024
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.

2 participants