Skip to content

Conversation

hhjin1
Copy link
Collaborator

@hhjin1 hhjin1 commented Feb 18, 2025

요구사항

기본

  • 중상품 데이터 정보는 https://panda-market-api.vercel.app/docs/#/ 에 명세된 GET 메소드 “/products” 를 사용해주세요.
  • '상품 등록하기' 버튼을 누르면 “/additem” 로 이동합니다. ( 빈 페이지 )
  • 전체 상품에서 드롭 다운으로 “최신 순” 또는 “좋아요 순”을 선택해서 정렬을 할 수 있습니다.

###중고마켓 반응형

베스트 상품

  • Desktop : 4개 보이기
  • [] Tablet : 2개 보이기
  • [] Mobile : 1개 보이기
    전체 상품
  • Desktop : 12개 보이기
  • [] Tablet : 6개 보이기
  • [] Mobile : 4개 보이기

심화

  • 페이지네이션 가능

멘토에게

  • 템플릿코드 사용했습니다.
  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@hhjin1 hhjin1 self-assigned this Feb 18, 2025
@hhjin1 hhjin1 added the 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. label Feb 18, 2025
@hhjin1 hhjin1 requested a review from kiJu2 February 19, 2025 05:50
@kiJu2
Copy link
Collaborator

kiJu2 commented Feb 20, 2025

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

@kiJu2
Copy link
Collaborator

kiJu2 commented Feb 20, 2025

굿굿 ! 템플릿 커밋 구분을 해주셨군요 !
혜진님께서 작성하신 코드 위주로 꼼꼼히 리뷰해보도록 할게요 😊

@@ -0,0 +1 @@
REACT_APP_BASE_URL=https://panda-market-api.vercel.app
Copy link
Collaborator

Choose a reason for hiding this comment

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

훌륭합니다 ! 환경변수로 BASE_URL을 지정하셨군요 !

굿굿 ~! 환경변수는 다음과 같은 이점들이 있지요:

왜 환경 변수에 저장해야 하나요?

개발(dev), 테스트(test), 실제 사용(prod) 등 다양한 환경에서 앱을 운영하게 되는 경우, 각 환경에 따라 다른 base URL을 사용해야 할 수 있습니다. 만약 코드 내에 하드코딩되어 있다면, 각 환경에 맞춰 앱을 배포할 때마다 코드를 변경해야 하며, 이는 매우 번거로운 작업이 됩니다. 하지만, 환경 변수를 .env.production, .env.development, .env.test와 같이 설정해두었다면, 코드에서는 단지 다음과 같이 적용하기만 하면 됩니다.

const apiUrl = `${process.env.REACT_APP_BASE_URL}/api`;

이러한 방식으로 환경 변수를 사용하면, 배포 환경에 따라 쉽게 URL을 변경할 수 있으며, 코드의 가독성과 유지보수성도 개선됩니다.

실제 코드 응용과 관련해서는 다음 한글 아티클을 참고해보세요! => 보러가기

@@ -0,0 +1 @@
REACT_APP_BASE_URL=https://panda-market-api.vercel.app
Copy link
Collaborator

Choose a reason for hiding this comment

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

환경변수를 .gitignore에 추가해보시는건 어떨까요?

.env 파일은 보통 API 키, 데이터베이스 비밀번호, 서버 URL 등 중요한 설정값을 저장하는 파일이에요.
이런 파일을 형상관리(Git)에 포함하면 보안 문제가 발생할 수 있어요.

  1. 보안 문제 (API 키 & 비밀번호 노출)
    예를 들어, 아래와 같은 .env 파일이 있다고 가정해볼게요.
REACT_APP_API_KEY=123456789abcdef
DATABASE_PASSWORD=my-secret-password

이 파일을 Git에 올리면 누구나 볼 수 있어요.
만약 GitHub에 올라가면, 악의적인 사용자가 API를 도용하거나, 데이터베이스에 무단 접근할 수도 있어요! 😱

  1. 환경별 설정값이 다를 수 있음 (개발/운영 분리)
    개발할 때는 테스트 서버를 사용하지만, 실제 서비스에서는 운영 서버를 사용해야 해요.
    만약 .env가 Git에 포함되면, 모든 사람이 같은 설정을 쓰게 되어 개발 환경과 운영 환경을 구분할 수 없어요.

✅ 올바른 방법
.env.development → 개발용
.env.production → 운영용
실제 실행할 때 .env 파일을 개별적으로 설정

그래서 어떻게 설정할까?

# .gitignore
.env

위와 같이 추가해주시면 됩니다 !

Comment on lines +22 to +26
const queryParams = new URLSearchParams({
page,
pageSize,
orderBy,
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

오우 ! URLSearchParams를 사용하셨군요 ? 😊

Comment on lines +22 to +29
const queryParams = new URLSearchParams({
page,
pageSize,
orderBy,
});

if (keyword) {
queryParams.append("keyword", keyword);
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
const queryParams = new URLSearchParams({
page,
pageSize,
orderBy,
});
if (keyword) {
queryParams.append("keyword", keyword);
const queryParams = new URLSearchParams({
page,
pageSize,
orderBy,
keyword
});

Comment on lines +32 to +35
const response = await fetch(
`https://panda-market-api.vercel.app/products?${queryParams.toString()}`
);
if (!response.ok) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

BASE_URL을 정의하셨기에 다음과 같이 작성해볼 수 있어요 !

Suggested change
const response = await fetch(
`https://panda-market-api.vercel.app/products?${queryParams.toString()}`
);
if (!response.ok) {
const response = await fetch(
`${BASE_URL}/products?${queryParams.toString()}`
);
if (!response.ok) {

}

const response = await fetch(
Copy link
Collaborator

Choose a reason for hiding this comment

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

axios를 사용해보는건 어떨까요?(제안/선택)

fetch 모듈을 잘 만든다는 것은 어렵습니다. 다음 사항들을 고려해볼 수 있어요:

  1. 만약 get이 아닌 메써드(post, patch, delete 등)일 경우는 어떻게 처리할 수 있을까요?
  2. querybody가 필요할 때는 어떻게 처리 할 수 있을까요?
  3. 로그인 인가를 위한 토큰을 request 전에 자동으로 삽입할 수는 없을까요? (인증/인가를 자동으로 할 수 없을까요?)
  4. 처음 한 번에 Base URL을 지정할 수는 없을까요?
    1. Base URL을 사용하다가 타 Domain에 보내야 될 때는 어떻게 할 수 있을까요?
      이 모든 요구사항들을 '잘 만든다는 것'은 어려워요. 따라서 이 모든걸 만들어진 fetch 모듈을 사용해보고 후에 fetch모듈을 만들어 보는 것도 좋은 학습 방법이 될 수 있어요.

axios 시작하기

어떻게 세팅하면 될까? 🤔

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

인가에 필요한 accessTokenlocalStorage가 있다면 axios의 인터셉터를 활용할 수 있습니다 !

인터셉터는 혼자 해결해보시는 것을 권장드립니다. 혹시 모르시겠으면 다음 위클리 미션에 질문해주세요. 😊

사용 방법 🚀

사용 방법은 정말 간단해요. 다음과 같이 사용할 수 있습니다:

instance.get(`/user/${userId}`)

딱 보니. 마이그레이션도 정말 쉽게 할 수 있겠죠? 😊

axios API

Comment on lines +7 to +8
const imageURL =
item.images && item.images.length > 0 ? item.images[0] : placeholder;
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
const imageURL =
item.images && item.images.length > 0 ? item.images[0] : placeholder;
const imageURL = item?.images?.[0] ?? placeholder;

Copy link
Collaborator

@kiJu2 kiJu2 Feb 20, 2025

Choose a reason for hiding this comment

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

아. 추가로 이를 옵셔널 체이닝이라고 합니다 !

size === "large"
? items.slice(
0,
window.innerWidth <= 480 ? 1 : window.innerWidth <= 768 ? 2 : 4
Copy link
Collaborator

Choose a reason for hiding this comment

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

(제안) 480, 768과 같은 숫자가 많이 보이는군요 !

Suggested change
window.innerWidth <= 480 ? 1 : window.innerWidth <= 768 ? 2 : 4
window.innerWidth <= BREAKPOINTS.MOBILE ? 1 : window.innerWidth <= BREAKPOINTS.TABLET ? 2 : 4

앞으로도 재사용이 많을 것으로 예상되어 유지보수성과 가독성을 위해 상수로 정의해두면 어떨지 제안드려봅니다 !

@kiJu2
Copy link
Collaborator

kiJu2 commented Feb 20, 2025

굿굿 ! 정말 수고하셨습니다 혜진님 ㅎㅎㅎ
첫 과제를 성공적으로 수행하셨군요 ! 처음 도전을 하시는 만큼 여러 꿀팁들을 알려드리고 싶었어요.
과제 수행하시느라 정말 수고 많으셨습니다 혜진님 !
(이번 제출을 계기로 앞으로도 .. ! 💪)

@kiJu2 kiJu2 merged commit f4d976a into codeit-bootcamp-frontend:React-황혜진 Feb 20, 2025
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants