Skip to content
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

[김현묵] sprint 5 #97

Conversation

kimhyunmook
Copy link
Collaborator

@kimhyunmook kimhyunmook commented Oct 28, 2024

요구사항

기본

  • Github에 스프린트 미션 PR을 만들어 주세요.
  • React를 사용해 진행합니다.

중고마켓 페이지

  • PC, Tablet, Mobile 디자인에 해당하는 중고마켓 페이지를 만들어 주세요.
  • 중고마켓 페이지 url path는 별도로 설정하지 않고, ‘/’에 보이도록 합니다.
  • 상품 데이터는 https://panda-market-api.vercel.app/docs/에 명세된 GET 메소드 “/products” 를 사용해주세요.
  • 상단 네비게이션 바, 푸터는 랜딩 페이지와 동일한 스타일과 규칙으로 만들어주세요.
  • 상품 데이터는 https://panda-market-api.vercel.app/docs/에 명세된 GET 메소드 “/products” 를 활용해주세요.
  • 상품 목록 페이지네이션 기능을 구현합니다.
  • 드롭 다운으로 “최신 순” 또는 “좋아요 순”을 선택해서 정렬을 구현하세요.
  • 상품 목록 검색 기능을 구현합니다.
  • 베스트 상품 데이터는 https://panda-market-api.vercel.app/docs/에 명세된 GET 메소드 “/products”의 정렬 기준 favorite을 사용해주세요.

심화

  • 커스텀 hook을 만들어 필요한 곳에 활용해 보세요.

중고마켓 페이지

  • 중고 마켓의 카드 컴포넌트 반응형 기준은 다음과 같습니다

멘토에게

  • 페이지 버튼 부분 저렇게 처리하는지 궁금합니다. pageNation

@kimhyunmook kimhyunmook requested a review from pers0n4 October 28, 2024 14:01
@kimhyunmook kimhyunmook changed the title Basic 김현묵 sprint5 [김현묵] sprint 5 Oct 28, 2024
@kimhyunmook kimhyunmook added 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. 최종 제출 스프린트미션 최종 제출본입니다. 제출일 이후 제출한PR 제출 마감일(일요일) 이후에 제출하는 PR입니다. labels Oct 28, 2024
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.

  1. PR CL(Change List)에 이번 스프린트 미션과는 관계 없는 파일들이 다수 보이는 것 같습니다. base branch와 target branch의 동기 지점을 고려해보면 좋을 것 같네요.

페이지 버튼 부분 저렇게 처리하는지 궁금합니다. pageNation

버튼 자체를 숨기는 방식도 유효하고, 노출하되 클릭하지 못하도록 disable 시키는 방법도 유효합니다.

usePageNavi,
useScreenSize,
} from "./hook/hook";
let init = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

const로 정의해도 객체 내부 값들은 변경할 수 있기 때문에 object 자체를 변경하려는 의도가 아니라면 const로 정의해도 충분할 것 같습니다.
그리고 init이라는 이름을 보면 애초에 초기값 전달을 목표로 정의한 걸로 보이는데, 그 의도가 맞다면 더더욱 const로 선언하고, 더 나아가서는 Object.freeze 등의 method를 활용할 수도 있을 것 같습니다.

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 +4 to +15
const [_list, _setList] = useState(items);
const [_length, _setLength] = useState(leng);
return {
value: _list,
setValue: (setItems) => {
_setList(setItems);
},
length: _length,
setLength: (setLeng) => {
_setLength(setLeng);
},
};
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 +22 to +29
start,
setStart: (startNum) => {
setStart(startNum);
},
last,
setLast: (lastNum) => {
setLast(lastNum);
},
Copy link
Collaborator

Choose a reason for hiding this comment

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

setStart와 setLast 둘 다 이름 그대로 넘겨도 될 것 같네요.

Comment on lines +17 to +29
const [sellLimit, setSellLimit] = useState(10);
const naviLimit = 5;
const bestProduct = useItmeList([], 4);
const sellProduct = useItmeList([], sellLimit);
const [onTarget, setOnTarget] = useState(1);
const [arrType, setArrType] = useState("recent");
const [total, setTotal] = useState(0);
const pageNavi = usePageNavi(1, 5);
const searchRef = useRef(null);
const searchHandle = useChange();
const windowSize = useScreenSize();
const [bestItmeSize, setBestItemSize] = useState("282px");
const [sellItmeSize, setSellItemSize] = useState("220px");
Copy link
Collaborator

Choose a reason for hiding this comment

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

하나의 컴포넌트에 정의된 상태가 너무 많아 보이네요. 넘길 수 있는 것들은 위임시키는 형태로 줄여보시면 좋을 것 같네요.

};

const searchKewordHandle = (e) => {
if (e.keyCode === 13 || e.type.toString() === "click")
Copy link
Collaborator

Choose a reason for hiding this comment

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

13은 무슨 값일까요? (질문의 의도가 무엇일까요? 👀 )

Comment on lines +140 to +141
sellProduct.setValue(res.list);
setTotal(res.totalCount / sellLimit);
Copy link
Collaborator

Choose a reason for hiding this comment

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

product에 따라 종속성이 생기는 total도 위 코멘트와 같습니다. 이 경우라면 state를 object 형태로 관리하는 걸 고려해볼 수 있겠습니다.

Comment on lines +163 to +193
<div className="marketEtc">
<div className="searchBox">
<button className="submit" onClick={searchKewordHandle}>
<img src="./img/ic_search.svg" alt="search" />
</button>
<input
type="text"
ref={searchRef}
onChange={searchHandle.onChange}
onKeyDown={searchKewordHandle}
className="marketSearch"
placeholder="검색할 상품을 입력해주세요"
/>
</div>
<a href="#">상품등록하기</a>
<select onChange={selectHandle}>
<option value="recent" defaultChecked>
최신순
</option>
<option value="favorite">좋아요순</option>
</select>
</div>
</MarketSection>
<MarketPageNavi
start={pageNavi.start}
last={pageNavi.last}
target={onTarget}
onClick={pageNaviEvent}
onNext={nextEvent}
onPrivous={privousEvent}
total={total}
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 +10 to +11
let path = `${url}?page=${page}&pageSize=${pageSize}&orderBy=${orderBy}`;
if (!!keyword) path += `&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.

URL을 다양하게 다뤄야 한다면 스트링 값을 더하고 빼는 것 대신 URL와 URLSearchParams 내장 객체를 참고해보시면 좋을 것 같습니다.

Comment on lines +146 to +197
<div className="App" style={init}>
<Header />
<div className="container">
<MarketSection
className={"best"}
title={"베스트 상품"}
data={bestProduct.value}
itemMaxWidth={bestItmeSize}
skeletonLength={bestProduct.length}
/>
<MarketSection
className={"sell"}
title={"판매 중인 상품"}
data={sellProduct.value}
itemMaxWidth={sellItmeSize}
skeletonLength={sellProduct.length}
>
<div className="marketEtc">
<div className="searchBox">
<button className="submit" onClick={searchKewordHandle}>
<img src="./img/ic_search.svg" alt="search" />
</button>
<input
type="text"
ref={searchRef}
onChange={searchHandle.onChange}
onKeyDown={searchKewordHandle}
className="marketSearch"
placeholder="검색할 상품을 입력해주세요"
/>
</div>
<a href="#">상품등록하기</a>
<select onChange={selectHandle}>
<option value="recent" defaultChecked>
최신순
</option>
<option value="favorite">좋아요순</option>
</select>
</div>
</MarketSection>
<MarketPageNavi
start={pageNavi.start}
last={pageNavi.last}
target={onTarget}
onClick={pageNaviEvent}
onNext={nextEvent}
onPrivous={privousEvent}
total={total}
/>
</div>
<Footer />
</div>
Copy link
Collaborator

Choose a reason for hiding this comment

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

React에서 마크업을 구성할 때는 비슷한 추상화 수준을 유지시켜주면 가독성 향상에 도움이 많이 됩니다. Header와 Footer처럼 중간이 있는 div 부분도 컴포넌트로 한 번 분리되면 좋을 것 같네요.

@pers0n4 pers0n4 merged commit 4b757d7 into codeit-sprint-fullstack:react-김현묵 Oct 31, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. 제출일 이후 제출한PR 제출 마감일(일요일) 이후에 제출하는 PR입니다. 최종 제출 스프린트미션 최종 제출본입니다.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants