Skip to content

Conversation

@heewls
Copy link
Collaborator

@heewls heewls commented Feb 14, 2025

요구사항

기본

  • 각 상품 클릭 시 상품 상세 페이지로 이동합니다.
  • 상품 상세 페이지 주소는 “/items/{productId}” 입니다.
  • response 로 받은 데이터로 화면을 구현합니다
  • 목록으로 돌아가기 버튼을 클릭하면 중고마켓 페이지 주소인 “/items” 으로 이동합니다
  • 문의하기에 내용을 입력하면 등록 버튼의 색상은 “3692FF”로 변합니다.
  • response 로 받은 데이터로 화면을 구현합니다

심화

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

주요 변경사항

스크린샷

멘토에게

  • comments data 다 보여주기에는 무리가 있을 거 같아서 우선 limit 고정값 3으로 불러왔습니다

@heewls heewls changed the title [김희진] sprint3 [김희진] sprint7 Feb 14, 2025
@heewls heewls self-assigned this Feb 14, 2025
@heewls heewls added the 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. label Feb 14, 2025
@kiJu2
Copy link
Collaborator

kiJu2 commented Feb 15, 2025

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

@@ -0,0 +1,11 @@
import axios from "axios";
Copy link
Collaborator

Choose a reason for hiding this comment

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

axios는 instance를 만드셔서 사용해볼 수 있습니다 ! 🤗

instance를 만들어서 export를 하고 사용해보는 것 정도로 시도해보면 좋을 것 같아요. axios-instance 파일을 만들어서 instance를 생성하고 export한 후 사용해보는건 어떨까요?
다음과 같이 만들어볼 수 있어요:

const baseURL = process.env.NEXT_PUBLIC_LINKBRARY_BaseURL;

const instance = axios.create({
  baseURL: baseURL,
  headers: {
    'Content-Type': 'application/json',
  },
});

export default instance

axios instance

Comment on lines +5 to +11
export async function getComments(productId) {
const response = await axios.get(
`${BASE_URL}/products/${productId}/comments?limit=3`
);

return response.data.list;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

다음과 같이 파라메터에 기본값을 지정하여 불러올 수 있겠군요 ! 😊

Suggested change
export async function getComments(productId) {
const response = await axios.get(
`${BASE_URL}/products/${productId}/comments?limit=3`
);
return response.data.list;
}
export async function getComments(productId, limit = 3) {
const response = await axios.get(
`${BASE_URL}/products/${productId}/comments?limit=${limit}`
);
return response.data.list;
}

혹시 모를 성능까지 고려하시다니 👍

Copy link
Collaborator

Choose a reason for hiding this comment

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

(더 나아가서)쿼리는 URLSearchParams로 손쉽게 사용할 수 있어요 !

다음과 같이요 !:

    const params = new URLSearchParams({ limit: '100' });
    const { data } = await instance.get(`/articles/${articleId}/comments`, { params });

희진님 코드에 적용해보면:

Suggested change
export async function getComments(productId) {
const response = await axios.get(
`${BASE_URL}/products/${productId}/comments?limit=3`
);
return response.data.list;
}
export async function getComments(productId, params) {
const query = (new URLSearchParams(params));
const response = await axios.get(
`${BASE_URL}/products/${productId}/comments?limit=3`,
{ params }
);
return response.data.list;
}

axios를 사용하실 경우 URLSearchParams와 함께 객체로 손쉽게 핸들링할 수 있습니다 !
객체로 구성할 수 있어 가독성이 좋고, URL 인코딩을 자동으로 처리하여 특수 문자나 공백이 포함된 값에서도 안전하게 동작합니다 !

URLSearchParams: URLSearchParams 인터페이스는 URL의 쿼리 문자열을 대상으로 작업할 수 있는 유틸리티 메서드를 정의합니다.

쿼리를 생성하실 때에 참고해서 사용해보세요 😊

Comment on lines +9 to +24
<S.CommentContainer>
<Input
label="문의하기"
placeholder="개인정보를 공유 및 요청하거나, 명예 훼손, 무단 광고, 불법 정보 유포시 모니터링 후 삭제될 수 있으며, 이에 대한 민형사상 책임은 게시자에게 있습니다."
height="104px"
largeHeight="140px"
isTextarea
value={comment}
onChange={(e) => setComment(e.target.value)}
/>
<S.RegisterBtn>
<button disabled={!comment.trim()} onClick={() => setComment("")}>
등록
</button>
</S.RegisterBtn>
</S.CommentContainer>
Copy link
Collaborator

Choose a reason for hiding this comment

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

CommentContainerform으로 지정해볼 수도 있겠군요 !

submit이 목적인 컨테이너는 form 기반의 스타일 태그로 만들어보는 것도 고려해볼 수 있어요 !
다음과 같이요 !:

export const CommentContainer = styled.form`

Comment on lines +28 to +32
useEffect(() => {
getProductInfo(productId)
.then((result) => setProduct(result))
.catch((error) => console.error(error));
}, []);
Copy link
Collaborator

Choose a reason for hiding this comment

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

productId를 의존하고 있으므로 의존성에 넣으시는게 좋을 것 같아요 😊

Suggested change
useEffect(() => {
getProductInfo(productId)
.then((result) => setProduct(result))
.catch((error) => console.error(error));
}, []);
useEffect(() => {
getProductInfo(productId)
.then((result) => setProduct(result))
.catch((error) => console.error(error));
}, [productId]);

Comment on lines +4 to +19
export default function User({ owner, createdAt, detail }) {
const date = new Date(createdAt);
const formattedDate = `${date.getFullYear()}.${String(
date.getMonth() + 1
).padStart(2, "0")}.${String(date.getDate()).padStart(2, "0")}`;

return (
<S.User $detail={detail}>
<S.Profile src={user} $detail={detail} alt="profile" />
<S.UserInfo>
<S.Name $detail={detail}>{owner}</S.Name>
<S.CreatedAt $detail={detail}>{formattedDate}</S.CreatedAt>
</S.UserInfo>
</S.User>
);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

(제안) (어떤 UI인지는 모르겠으나..) UI를 유추 가능한 컴포넌트 이름으로 짓는게 어떨까요?

UserCard 혹은 UserAvatar와 같이 UI를 유추 가능할 수 있도록 이름을 변경하면 어떨지 제안드립니다 ! ㅎㅎㅎ

@kiJu2
Copy link
Collaborator

kiJu2 commented Feb 15, 2025

역시 희진님 ~! 😊 빠르게 미션을 수행하셨군요 !
컴포넌트는 크게 손 볼 것이 딱히 보이지 않아요 ! 잘하셨어요. 👍
통신 레이어에서 제안드리고 싶은 것들이 있어서 리뷰해봤습니다 !

미션 수행하시느라 정말 수고 많으셨습니다. 희진님 ! 👍👍

@kiJu2 kiJu2 merged commit 275e855 into codeit-bootcamp-frontend:React-김희진 Feb 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