Skip to content

Conversation

@BaeZzi813
Copy link
Collaborator

요구사항

  • Github에 PR(Pull Request)을 만들어서 미션을 제출합니다.
  • 피그마 디자인에 맞게 페이지를 만들어 주세요.
  • React를 사용합니다

기본

상품 상세
  • 상품 상세 페이지 주소는 "/items/{productId}" 입니다.

  • response 로 받은 아래의 데이터로 화면을 구현합니다.
    => favoriteCount : 하트 개수
    => images : 상품 이미지
    => tags : 상품태그
    => name : 상품 이름
    => description : 상품 설명

  • 목록으로 돌아가기 버튼을 클릭하면 중고마켓 페이지 주소인 "/items" 으로 이동합니다

상품 문의 댓글
  • 문의하기에 내용을 입력하면 등록 버튼의 색상은 "3692FF"로 변합니다.
  • response 로 받은 아래의 데이터로 화면을 구현합니다
    => image : 작성자 이미지
    => nickname : 작성자 닉네임
    => content : 작성자가 남긴 문구
    => description : 상품 설명
    => updatedAt : 문의글 마지막 업데이트 시간

심화

  • 모든 버튼에 자유롭게 Hover효과를 적용하세요.

주요 변경사항

  • 기존의 Styled Components 에서 Tailwind CSS 로 작업 이어갔습니다.

스크린샷

PC Tablet Mobile
PC 화면 Tablet 화면 Mobile 화면
PC Tablet Mobile
PC 화면 Tablet 화면 Mobile 화면

멘토에게

  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@BaeZzi813 BaeZzi813 requested a review from kiJu2 September 13, 2025 05:41
@BaeZzi813 BaeZzi813 added the 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. label Sep 13, 2025
@kiJu2 kiJu2 changed the base branch from main to React-양재영 September 15, 2025 02:12
@kiJu2
Copy link
Collaborator

kiJu2 commented Sep 15, 2025

스프리트 미션 하시느라 수고 많으셨어요.
학습에 도움 되실 수 있게 꼼꼼히 리뷰 하도록 해보겠습니다. 😊

Comment on lines +18 to +47
export async function getProductDetails(productId) {
try {
const response = await instance.get(`/products/${productId}`);
return response.data;
} catch (error) {
throw new Error(`상품을 불러오는데 실패했습니다 : ${error.message}`);
}
}

export async function getProductComments(productId, limit = 5, cursor) {
try {
const params = { limit };
if (cursor) params.cursor = cursor;
const response = await instance.get(`/products/${productId}/comments`, {
params,
});
return response.data;
} catch (error) {
throw new Error(`상품을 불러오는데 실패했습니다 : ${error.message}`);
}
}

export async function postProducts(body) {
try {
const response = await instance.post("/products/", body);
return response.data;
} catch (error) {
throw new Error(`상품을 등록하는데 실패했습니다 : ${error.message}`);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

크으 ~ API 함수가 정말 깔끔하네요 👍👍

에러 처리, axios의 파라메터도 적절하게 잘 채워넣으셨구요 ! 굿굿 !

Comment on lines +12 to +17
export const ERROR_STATUSCODE_MESSAGES = {
401: "인증이 필요합니다. 로그인 해주세요.",
403: "접근 권한이 없습니다.",
404: "요청하신 리소스를 찾을 수 없습니다.",
500: "서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요.",
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

크으 ~ 상태 코드에 맞는 안내메시지도 정의해두셨군요 ! 😉

이렇게 해두면 활용성이 좋겠어요 !

Comment on lines +26 to +28
alert(
ERROR_STATUSCODE_MESSAGES[status] || "알 수 없는 오류가 발생했습니다."
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

공통 API 함수에 alert를 표시해두셨군요 !

이렇게 되면 모든 리소스 요청에 alert가 출력되겠어요 !
예외적으로 처리해야 되는 상황에서는 어떻게 할지 고려해볼 수 있겠네요.

예를 들어서, 디자이너가

  • 판다마켓 상품 등록에서 필수 파라메터가 모두 채워지지 않았을 경우 채워지지 않은 input에 하이라이팅을 해달라는 요청이 있다면 ?
  • 방금 사례는 클라이언트 유효성 검사로 가능하다 친다면, 혹은 회원가입 시 이메일 중복에 의한 에러를 alert가 아닌 toast로 보여주고 싶다면?

모든 통신에 대한 UI를 일관되게 처리하게 된다면 위와 같은 상황에 유연하게 대처하기 어려울 수 있을 것 같아요 !
또한, AxiosInstance에 여러 책임을 가지게 되므로 구조상의 잠재적 문제도 고려해볼 수 있을 것 같아요.
AxiosInstance는 HTTP Client의 역할을 수행하면서 사용자의 UI에도 관여하고 있군요 !

그래서 이러한 문제는 어떻게 해결하면 좋을까?

UI와 관련된 것은 리액트 단(컴포넌트)에서 처리해보는 것을 고려해볼 수 있겠네요 😉
통신 과정에서 에러가 발생하면 로깅을 해두고 에러를 다시 throw하여(이미 잘 해두고 계십니다 !) 컴포넌트에서 예외처리를 하는 방법이 고려될 수 있을 것 같아요 😊

Comment on lines +4 to +7
const options = [
{ label: "최신순", value: "recent" },
{ label: "좋아요순", value: "favorite" },
];
Copy link
Collaborator

Choose a reason for hiding this comment

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

크으 ~ 컴포넌트 바깥에 선언해두셨군요 !

좋습니다. 이제 컴포넌트 내부에는 컴포넌트 자원을 사용하는 로직들로만 구성되어 있게되었어요 👍👍

Comment on lines +21 to +23
} catch (error) {
throw new Error(`상품을 불러오는데 실패했습니다 : ${error.message}`);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

(이어서) 여기서 사용자에게 에러를 출력해줄 수 있겠군요 ! 😉

Comment on lines +15 to +20
const [itemRes, commentRes] = await Promise.all([
getProductDetails(productId),
getProductComments(productId),
]);
setItemInfo(itemRes);
setCommentInfo(commentRes);
Copy link
Collaborator

Choose a reason for hiding this comment

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

크으 ~ 훌륭합니다 ! 병렬처리를 하셨군요 !

현재 직렬 처리 getProductDetails이 끝날 때 까지 기다린 후 getProductComments를 실행해야 할 이유가 없지요 !
성능까지 고려하시다니 훌륭합니다 ! 👍

@kiJu2
Copy link
Collaborator

kiJu2 commented Sep 15, 2025

크으 ~ 재영님 멋집니다. 단순히 미션의 요구사항을 만족시키려는 것 뿐 아니라 "어떻게 해야 더 나은 성능과 구조로 개발할 수 있을까?"를 고민하시는게 느껴져요.
덕분에 저도 재영님의 의도를 파악하면서 리뷰하는 재미가 쏠쏠했습니다 😉😉

가면 갈수록 재영님의 성장이 가파르게 진행되는게 느껴집니다 !
이번 미션 정말 수고 많으셨습니다 ☺️

@kiJu2 kiJu2 merged commit 84d4f8c into codeit-bootcamp-frontend:React-양재영 Sep 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants