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

[박수환] sprint5 #86

Conversation

soohwanpak
Copy link
Collaborator

요구사항

기본 요구사항

공통

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

배포 주소 : https://funny-shortbread-b8c7a8.netlify.app/

중고마켓 페이지

  • 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을 만들어 필요한 곳에 활용해 보세요.

중고마켓 페이지

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

주요 변경사항

멘토에게

  • 아직 구현 못한 것들이 있는데 코드리뷰 받으며 추가로 작업하여 수정하겠습니다.

@soohwanpak soohwanpak added 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. 미완성🫠 완성은 아니지만 제출합니다... labels Oct 27, 2024
@soohwanpak soohwanpak requested a review from pers0n4 October 27, 2024 14:13
@soohwanpak soohwanpak self-assigned this Oct 27, 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.

커밋 단위를 '코드에 의미 있는 변화가 생기는 지점'을 기준으로 잘 게 나누어서 커밋할 수 있도록 노력해보시면 좋을 것 같습니다.

Comment on lines +25 to +27
if (width >= 1230) setPageSize(10);
if (width >= 801 && width < 1230) setPageSize(6);
if (width < 800) setPageSize(4);
Copy link
Collaborator

Choose a reason for hiding this comment

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

조건문 코드 스타일만 조금 수정해줘도 가독성이 개선될 것 같습니다.


function AllItem() {
const [products, setProducts] = useState([]);
const [option, setOption] = useState('favorite');
Copy link
Collaborator

Choose a reason for hiding this comment

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

enum처럼 사용되는 값이면 리터럴 값을 그대로 사용하는 것보다 const object로 정의해두고 사용하면 좋을 것 같네요.

Comment on lines +7 to +8
const [tempSearch, setTempSearch] = useState("");
const [search, setSearch] = useState("");
Copy link
Collaborator

Choose a reason for hiding this comment

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

tempSearch와 search라는 상태가 동시에 존재한다는 게 상태 관리 차원에서 불편한 느낌이드네요.

  1. 정말 tempSearch라는 상태가 필요한가요?
  2. 진짜 필요하다면 tempSearch보다 더 적절한 이름을 짓는 게 맞을 것 같습니다.

const [totalCount, setTotalCount] = useState(0);

const totalPages = Math.ceil(totalCount / pageSize);
const startPage = ~~((page - 1) / 5) * 5 + 1;
Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. bitwise operator를 직접 사용한들 성능이 유의미하게 개선된다고 보기는 힘듭니다. 차라리 바로 윗 줄 코드처럼 Math 객체의 method를 사용해서 가독성을 높이는 게 좋아보입니다.
  2. / 5와 * 5는 같은 맥락으로 사용되는 값일까요? -1, +1은 0, 1 인덱스 범위 조정 차원에서 많이 쓰이는 값이기 때문에 넘어간다고 해도 5 같은 값은 상수로 정의해두고 사용하는 게 좋습니다.

Comment on lines +16 to +20
const updateProducts = async () => {
const axiosProducts = await getProductsList(page, search, option, pageSize);
setProducts(axiosProducts.products);
setTotalCount(axiosProducts.totalCount);
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

products와 totalCount는 하나의 API를 호출할 때 같이 반환되는 값인데 굳이 state를 분리할 이유가 없어 보입니다. (API 호출 시 동시에 변경되는 값이기 때문)
이 경우는 객체 자체를 state로 가져가는 쪽이 좋아 보이네요.

setPage(1);
}
const onKeyDown = (e) => {
if (e.keyCode === 13) {
Copy link
Collaborator

@pers0n4 pers0n4 Oct 30, 2024

Choose a reason for hiding this comment

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

13이 뭘까요? (질문의 의도가 무엇일까요? 👀)

Comment on lines +143 to +160
(products.map((product, index) => (
<div key={index} className='All-item-list-item'>
<div className='contain-img'>
<img src={product.images} alt={product.name} />
</div>
<div className='contain-text'>
<div className='contain-text-product-des'>{product.name}</div>
<div className='contain-text-price'>{product.price}원</div>
<div className='contain-text-like'>
<a className='like-button'>
<span className="material-symbols-outlined favorite-icon">
favorite
</span>
</a>
{product.favoriteCount}</div>
</div>
</div>
))
Copy link
Collaborator

Choose a reason for hiding this comment

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

products로 매핑하고 있는 부분을 컴포넌트로 분리해보시면 좋을 것 같습니다.

Comment on lines +182 to +217
{startPage + 1 <= totalPages && (
<button
value={startPage + 1}
onClick={onClickPage}
className={`buttonNum ${page === startPage + 1 ? 'active' : ''}`}
>
{startPage + 1}
</button>
)}
{startPage + 2 <= totalPages && (
<button
value={startPage + 2}
onClick={onClickPage}
className={`buttonNum ${page === startPage + 2 ? 'active' : ''}`}
>
{startPage + 2}
</button>
)}
{startPage + 3 <= totalPages && (
<button
value={startPage + 3}
onClick={onClickPage}
className={`buttonNum ${page === startPage + 3 ? 'active' : ''}`}
>
{startPage + 3}
</button>
)}
{startPage + 4 <= totalPages && (
<button
value={startPage + 4}
onClick={onClickPage}
className={`buttonNum ${page === startPage + 4 ? 'active' : ''}`}
>
{startPage + 4}
</button>
)}
Copy link
Collaborator

Choose a reason for hiding this comment

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

반복문을 활용해보세요. 또는 Array.prototype.map

Comment on lines +22 to +40
<div key={index} className='ItemComponent'>
<div className='contain-img'>
<img src={product.images} alt={product.name} />
</div>
<div className='contain-text'>
<div className='contain-text-product-des'>{product.name}</div>
<div className='contain-text-price'>{product.price}원</div>
<div className='contain-text-like'>
<a className='like-button'>
<span className="material-symbols-outlined favorite-icon">
favorite
</span>
</a>
<div className='contain-text-like-fs'>
{product.favoriteCount}
</div>
</div>
</div>
</div>
Copy link
Collaborator

Choose a reason for hiding this comment

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

이런 부분도 컴포넌트로 정의하면 좋을 것 같네요.


const getProductsList = async (page=1, search="", option="favorite", pageSize=10) => {
try {
const response = await axios.get(`https://panda-market-api.vercel.app/products?page=${page}&pageSize=${pageSize}&orderBy=${option}&keyword=${search}`);
Copy link
Collaborator

Choose a reason for hiding this comment

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

api 주소 값은 재사용되면서 환경에 따라 바뀔 수 있는 값이기에 우선은 상수로 정의해서 동일한 API 주소에 대해선 같이 사용할 수 있게 하면 좋을 것 같습니다.

@pers0n4 pers0n4 merged commit 75bcc13 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
매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. 미완성🫠 완성은 아니지만 제출합니다...
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants