Skip to content

[양재영] sprint 5 #99

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

Conversation

BaeZzi813
Copy link
Collaborator

@BaeZzi813 BaeZzi813 commented Aug 2, 2025

요구사항

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

기본

  • 중고마켓 페이지 주소는 “/items” 입니다.

  • 페이지 주소가 “/items” 일때 상단네비게이션바의 '중고마켓' 버튼의 색상은 “3692FF”입니다.

  • 상단 네비게이션 바는 이전 미션에서 구현한 랜딩 페이지와 동일한 스타일로 만들어 주세요.

  • 상품 데이터 정보는 https://panda-market-api.vercel.app/docs/#/ 에 명세된 GET 메소드 “/products” 를 사용해주세요.

  • 상품 등록하기' 버튼을 누르면 “/additem” 로 이동합니다. ( 빈 페이지 )

  • 전체 상품에서 드롭 다운으로 “최신 순” 또는 “좋아요 순”을 선택해서 정렬을 할 수 있습니다.

  • 중고마켓 반응형

  • 베스트 상품

    • Desktop: 4개
    • Tablet: 2개
    • Mobile: 1개
  • 전체 상품

    • Desktop: 10개
    • Tablet: 6개
    • Mobile: 4개

심화

  • 페이지 네이션 기능을 구현합니다.

주요 변경사항

스크린샷

localhost_5173_items (1) localhost_5173_items localhost_5173_items(2)

멘토에게

  • 전체상품의 orderBy 에 따른 최신순 좋아요순을 selectoption을 사용 하였는데 반응형 모바일 사이즈에서 이미지 변경이 궁금합니다.
  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@BaeZzi813 BaeZzi813 added the 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. label Aug 2, 2025
@BaeZzi813 BaeZzi813 requested a review from kiJu2 August 2, 2025 03:20
Comment on lines +40 to +64
{isMobile ? (
<div className="total-products-container">
<div className="products-title-mobile">
<h1 className="products-title">전체 상품</h1>
<Link to="/additem" className="add-item-button">
상품 등록하기
</Link>
</div>
<div className="total-products-content">
<div className="total-products-content-input">
<img src={searchIcon} alt="검색 아이콘" />
<input
type="text"
placeholder="검색할 상품을 입력해주세요"
value={keyword}
onChange={onKeywordChange}
/>
</div>
<select onChange={onOrderChange} value={orderBy}>
<option value="recent">최신순</option>
<option value="favorite">좋아요순</option>
</select>
</div>
</div>
) : null}
Copy link
Collaborator Author

@BaeZzi813 BaeZzi813 Aug 2, 2025

Choose a reason for hiding this comment

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

질문에 올린 select 이미지 설정법에 관한 useMediaQuery 로 모바일 사이즈일 때 구조 변경 코드줄 / 반응형 CSS 는 './ItemsPage.css'

Copy link
Collaborator

Choose a reason for hiding this comment

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

전체상품의 orderBy 에 따른 최신순 좋아요순을 select와 option을 사용 하였는데 반응형 모바일 사이즈에서 이미지 변경이 궁금합니다.

답변을 드리고 싶은데 잘 이해가 안되어서요 🥲
혹시 "select, option props를 전달하여 구성하였다."까지는 이해했는데요. 혹시 select 이미지 설정법이란게 어떤걸 의미하는걸까요 ?

DM 통해서 답변 주시거나 줌 미팅을 통해서도 답변드릴 수 있습니다 !

@kiJu2
Copy link
Collaborator

kiJu2 commented Aug 4, 2025

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

Comment on lines +1 to +6
export async function getProducts({
page = 1,
pageSize = 10,
orderBy = "recent",
keyword = "",
}) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

굿굿! 훌륭합니다 👍

백엔드 요구사항대로 파라메터를 잘 설계하셨네요 👍👍

orderBy = "recent",
keyword = "",
}) {
const params = new URLSearchParams({ page, pageSize, orderBy, keyword });
Copy link
Collaborator

Choose a reason for hiding this comment

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

크으 ~ 자바스크립트 임베드 객체인 URLSearchParams까지 제대로군요 ! 👍

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

Comment on lines +8 to +10
const response = await fetch(
`https://panda-market-api.vercel.app/products?${params}`
);
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 시작하기

Copy link
Collaborator

Choose a reason for hiding this comment

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

어떻게 세팅하면 될까? 🤔

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

}) {
const params = new URLSearchParams({ page, pageSize, orderBy, keyword });
const response = await fetch(
`https://panda-market-api.vercel.app/products?${params}`
Copy link
Collaborator

Choose a reason for hiding this comment

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

https://panda-market-api.vercel.app는 앞으로도 계속 사용되겠군요 !

이 때 환경 변수로 지정해두시면 편리합니다 !

환경 변수(Environment Variable): process.env에 내장되며 앱이 실행될 때 적용할 수 있는 값입니다!

다음과 같이 적용할 수 있습니다:

// .env.development
REACT_APP_BASE_URL="http://localhost:3000"

// .env.production
REACT_APP_BASE_URL="http://myapi.com"

// 사용시
<a href={`${process.env.REACT_APP_BASE_URL}/myroute`}>URL</a>

throw new Error("상품을 불러오는데 실패했습니다");
}
const data = await response.json();
return [data.list, data.totalCount];
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
return [data.list, data.totalCount];
return data;

배열로 반환하게 되면 반환되는 값이 어떤 값인지 유추하기 어려울 것으로 보입니다. 😊
이럴 때는 그냥 백엔드로부터 받은 데이터 그대로 반환해도 무방해보입니다 👍

alt={product.name}
/>
<h3 className="product-name">{product.name}</h3>
<p className="product-price">{product.price.toLocaleString()}원</p>
Copy link
Collaborator

Choose a reason for hiding this comment

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

<p> 태그는 단락을 나타냅니다 !

HTML <p> 요소는 하나의 문단을 나타냅니다. 시각적인 매체에서, 문단은 보통 인접 블록과의 여백과 첫 줄의 들여쓰기로 구분하지만, HTML에서 문단은 이미지나 입력 폼 등 서로 관련있는 콘텐츠 무엇이나 될 수 있습니다.

예를 들어 다음과 같은 값이 <p>태그에 적절할 수 있어요 😊:

Geckos are a group of usually small, usually nocturnal lizards. They are found on every continent except Antarctica.

혹은:

헌법재판소는 법관의 자격을 가진 9인의 재판관으로 구성하며, 재판관은 대통령이 임명한다. 선거에 있어서 최고득표자가 2인 이상인 때에는 국회의 재적의원 과반수가 출석한 공개회의에서 다수표를 얻은 자를 당선자로 한다.

MDN <p>


price는 어떤 태그가 적합할까?

Comment on lines +37 to +54
useEffect(() => {
async function fetchTotalProducts() {
try {
const [list, count] = await getProducts({
page,
pageSize: totalCountPerPage,
orderBy,
keyword,
});
setTotalProducts(list);
setTotalCount(count);
} catch (error) {
setError(error.message);
}
}

fetchTotalProducts();
}, [page, orderBy, keyword, totalCountPerPage]);
Copy link
Collaborator

Choose a reason for hiding this comment

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

굿굿. useEffect에 적절한 의존성이네요.

fetch 함수도 useEffect 안에서 선언함으로써 리렌더링 시 불필요한 재선언과 스코프도 명확하여 가독성도 챙길 수 있는 코드로 보입니다 👍👍

Comment on lines +3 to +8
export const useResponsive = () => {
const isTablet = useMediaQuery({ maxWidth: 1199 });
const isMobile = useMediaQuery({ maxWidth: 767 });

return isMobile ? [1, 4] : isTablet ? [2, 6] : [4, 10];
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

굿굿! 커스텀 훅을 만들어 재사용하셨군요 👍👍

@kiJu2
Copy link
Collaborator

kiJu2 commented Aug 4, 2025

수고하셨습니다 재영님~!
API 호출 로직이나 커스텀 훅 구성 등 훌륭하게 잘 구성하셨어요! 특히 파라미터 설계나 의존성 설정에 대한 이해도가 돋보였어요 👏
axios도 한 번 고려해보시고 시맨틱 마크업처럼 실무에서 자주 마주치는 요소도 더 익히시면 훨씬 탄탄한 프론트엔드 개발자로 성장하실 거예요! 😊

충분히 잘하시고 계십니다. 👍👍

질문에 대해 답변드리지 못해서 염려가 되는데요 ! 궁금하신 사항은 DM 주시면 조속히 답변드리도록 하겠습니다 😊

@kiJu2 kiJu2 merged commit b235cb8 into codeit-bootcamp-frontend:React-양재영 Aug 4, 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