Skip to content

React 이정윤 스프린트미션 5#56

Merged
pers0n4 merged 20 commits intocodeit-sprint-fullstack:react-이정윤from
jyoon00-cloud:react-이정윤
Sep 30, 2025

Hidden character warning

The head ref may contain hidden characters: "react-\uc774\uc815\uc724"
Merged

React 이정윤 스프린트미션 5#56
pers0n4 merged 20 commits intocodeit-sprint-fullstack:react-이정윤from
jyoon00-cloud:react-이정윤

Conversation

@jyoon00-cloud
Copy link
Collaborator

요구사항
기본 요구사항
공통

[x] Github에 스프린트 미션 PR을 만들어 주세요.
[x] React를 사용해 진행합니다.
중고마켓 페이지

[x] PC, Tablet, Mobile 디자인에 해당하는 중고마켓 페이지를 만들어 주세요.

[x] 중고마켓 페이지 url path는 별도로 설정하지 않고, '/'에 보이도록 합니다.

[x] 상단 네비게이션 바, 푸터는 랜딩 페이지와 동일한 스타일과 규칙으로 만들어주세요.

[x] 상품 데이터는 https://panda-market-api.vercel.app/docs/에 명세된 GET 메소드 "/products" 를 활용해주세요.

[x] 상품 목록 페이지네이션 기능을 구현합니다.
[x] 드롭 다운으로 "최신 순" 또는 "좋아요 순"을 선택해서 정렬을 구현하세요.
[x] 상품 목록 검색 기능을 구현합니다.
[x] 베스트 상품 데이터는 https://panda-market-api.vercel.app/docs/에 명세된 GET 메소드 "/products"의 정렬 기준 favorite을 사용해주세요.

심화 요구사항
공통

[x] 커스텀 hook을 만들어 필요한 곳에 활용해 보세요.
중고마켓 페이지

[x] 중고 마켓의 카드 컴포넌트 반응형 기준은 다음과 같습니다.
베스트 상품
Desktop : 4열
Tablet : 2열
Mobile : 1열
전체 상품
Desktop : 5열
Tablet : 3열
Mobile : 2열
반응형에 따른 페이지 네이션 기능을 구현합니다.
반응형으로 보여지는 물품들의 개수를 다르게 설정할때 서버에 보내는 pageSize값을 적절하게 설정합니다.

주요 변경사항

  • 리액트 기능 구현
  • api 기능 구현

스크린샷

image

멘토에게

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

Copy link
Collaborator

@pers0n4 pers0n4 left a comment

Choose a reason for hiding this comment

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

현재 React로 작성된 코드 구조가 html 파일처럼 작성되어 있는데, 아무래도 기존에 작성된 html 파일을 React로 전환하는 과정을 거치다 보니 그럴 수도 있을 것 같다는 생각이 듭니다.

React의 철학과 구조상 React를 잘 사용하기 위해서는 컴포넌트를 최대한 잘게 나누는 게 좋습니다. 극단적으로는 스타일이 적용되는 html element마다 하나의 컴포넌트로 정의할 수도 있습니다. 거의 모든 UI 라이브러리에서 html의 div, a, span 등을 Box나 Link, Text로 추상화하듯이 말이죠.
모든 기본 element를 React 컴포넌트로 바꾸는 것이 강제 되어야 하는 건 아니지만, 통으로 작성된 마크업은 적절한 단위로 나누어 보면 좋을 것 같습니다.

Copy link
Collaborator

Choose a reason for hiding this comment

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

같은 경로에 있는데 어떤 파일은 camelCase로, 어떤 파일은 PascalCase로 작성되어 있네요. 프로젝트 내 모든 파일이 같은 네이밍 케이스로 통일되어야 할 필요는 없지만, 최소한 같은 맥락상에 존재하는 파일들은 혼란을 줄이기 위해서 네이밍 케이스를 맞춰주는 게 좋습니다.

Copy link
Collaborator

Choose a reason for hiding this comment

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

main과 비슷해 보이는데 이 파일은 정체가 무엇인가요? 잘못 추가된 파일이라면 정리해주세요.

Comment on lines +9 to +15
const params = new URLSearchParams();
params.set("page", String(page));
params.set("pageSize", String(pageSize));
if (orderBy) params.set("orderBy", orderBy);
if (keyword) params.set("keyword", keyword);

const res = await fetch(`${BASE_URL}?${params.toString()}`);
Copy link
Collaborator

Choose a reason for hiding this comment

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

params는 URLSearchParams로 잘 처리하셨네요. url도 URL 인스턴스로 생성하면 search params를 포함해서 같이 처리할 수도 있답니다.

Copy link
Collaborator

Choose a reason for hiding this comment

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

커스텀 훅을 정의해두고 한 번도 사용하지 않은 건 조금 아쉽네요.
아무래도 useProducts 훅 자체가 재사용하기에 용이하지 않는 구조다 보니 그럴 수도 있을 것 같다 싶네요.
useProducts에서 처리하는 getProducts api를 직접 호출하는 페이지에서 실제로 어떻게 로직을 구성하셨는지 다시 파악해보고 useProducts 훅을 사용하기 좋은 구조로 바꿔보시면 좋을 것 같습니다.


export function useProducts({ page, sort, query, pageSize }) {
const [products, setProducts] = useState([]);
const [totalCount, setTotalCount] = useState(0);
Copy link
Collaborator

Choose a reason for hiding this comment

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

count 같은 값은 state로 정의하지 않아도 됩니다.
products.length로도 쉽게 알아낼 수 있고, api에서 반환되는 데이터를 함수 내부 지역 변수로 받아서 바로 반환할 수도 있습니다.

Comment on lines +5 to +16
const maxPageButtons = 5;
let startPage = Math.max(1, currentPage - Math.floor(maxPageButtons / 2));
let endPage = Math.min(totalPages, startPage + maxPageButtons - 1);

if (endPage - startPage + 1 < maxPageButtons) {
startPage = Math.max(1, endPage - maxPageButtons + 1);
}

const pageNumbers = [];
for (let i = startPage; i <= endPage; i++) {
pageNumbers.push(i);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

컴포넌트 내부에 명령형 코드가 많이 작성되는 경향은 코드를 읽기 어렵기 만들기 때문에 지양하는 게 좋습니다.

  1. 한두 줄로 끝나는 간단한 코드라면 선언형으로 작성하거나 e.g. Array.from(...)
  2. 조금 더 길거나 복잡한 로직이 들어가는 코드라면 책임 분리를 위해 커스텀 훅으로 구현하는 게 좋습니다.

@pers0n4 pers0n4 merged commit 0dc2a0e into codeit-sprint-fullstack:react-이정윤 Sep 30, 2025
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.

6 participants